From 28f7f3a226deb9686f06bbbca8c34302023235ef Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 26 Sep 2022 16:33:59 +0700 Subject: [PATCH] We are doing little visuals for cargo crates in minecarts --- .../ru/dbotthepony/mc/otm/entity/Ext.kt | 19 ++++++++ .../mc/otm/entity/MinecartCargoCrate.kt | 43 ++++++++++++++++++- .../mc/otm/menu/MinecartCargoCrateMenu.kt | 14 ++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/entity/Ext.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Ext.kt new file mode 100644 index 000000000..f9ec9cdbf --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Ext.kt @@ -0,0 +1,19 @@ +package ru.dbotthepony.mc.otm.entity + +import net.minecraft.network.syncher.EntityDataAccessor +import net.minecraft.network.syncher.SynchedEntityData +import net.minecraft.world.entity.Entity +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + +class SynchedEntityDataDelegate(private val type: EntityDataAccessor, private val data: SynchedEntityData) : ReadWriteProperty { + override fun getValue(thisRef: Entity, property: KProperty<*>): T { + return data.get(type) + } + + override fun setValue(thisRef: Entity, property: KProperty<*>, value: T) { + data.set(type, value) + } +} + +fun SynchedEntityData.delegate(type: EntityDataAccessor) = SynchedEntityDataDelegate(type, this) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt index 01cc046f7..3f6ded63c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/MinecartCargoCrate.kt @@ -1,6 +1,10 @@ package ru.dbotthepony.mc.otm.entity import net.minecraft.core.NonNullList +import net.minecraft.network.syncher.EntityDataAccessor +import net.minecraft.network.syncher.EntityDataSerializers +import net.minecraft.network.syncher.SynchedEntityData +import net.minecraft.sounds.SoundSource import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.vehicle.AbstractMinecartContainer @@ -10,11 +14,14 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.block.state.BlockState +import net.minecraft.world.level.gameevent.GameEvent import ru.dbotthepony.mc.otm.block.CargoCrateBlock import ru.dbotthepony.mc.otm.block.entity.CargoCrateBlockEntity +import ru.dbotthepony.mc.otm.core.position import ru.dbotthepony.mc.otm.menu.MinecartCargoCrateMenu import ru.dbotthepony.mc.otm.registry.MItems import ru.dbotthepony.mc.otm.registry.MRegistry +import ru.dbotthepony.mc.otm.registry.MSoundEvents class MinecartCargoCrate( type: EntityType<*>, @@ -48,7 +55,7 @@ class MinecartCargoCrate( } override fun getDefaultDisplayBlockState(): BlockState { - return block.defaultBlockState().setValue(CargoCrateBlock.IS_OPEN, false) + return block.defaultBlockState().setValue(CargoCrateBlock.IS_OPEN, interactingPlayers > 0) } override fun getDefaultDisplayOffset(): Int { @@ -66,4 +73,38 @@ class MinecartCargoCrate( override fun getPickResult(): ItemStack { return ItemStack(item, 1) } + + override fun defineSynchedData() { + super.defineSynchedData() + entityData.define(INTERACTING_PLAYERS, 0) + } + + var interactingPlayers by entityData.delegate(INTERACTING_PLAYERS) + + fun onPlayerOpen() { + if (isRemoved) + return + + if (interactingPlayers++ == 0) { + if (!isRemoved) { + level.playSound(null, this, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level.random.nextFloat() * 0.2f) + level.gameEvent(GameEvent.CONTAINER_OPEN, position, GameEvent.Context.of(this)) + } + } + } + + fun onPlayerClose() { + if (interactingPlayers <= 0) + return + + if (--interactingPlayers == 0) { + if (!isRemoved) { + level.gameEvent(GameEvent.CONTAINER_CLOSE, position, GameEvent.Context.of(this)) + } + } + } + + companion object { + val INTERACTING_PLAYERS: EntityDataAccessor = SynchedEntityData.defineId(MinecartCargoCrate::class.java, EntityDataSerializers.INT) + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MinecartCargoCrateMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MinecartCargoCrateMenu.kt index db2319829..e5d07b566 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MinecartCargoCrateMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MinecartCargoCrateMenu.kt @@ -16,6 +16,8 @@ class MinecartCargoCrateMenu @JvmOverloads constructor( ) : MatteryMenu(MMenus.CARGO_CRATE, p_38852_, inventory) { override val storageSlots: List + private val trackedPlayerOpen = !inventory.player.isSpectator + init { val container = cart as Container? ?: SimpleContainer(CargoCrateBlockEntity.CAPACITY) @@ -25,9 +27,21 @@ class MinecartCargoCrateMenu @JvmOverloads constructor( return@ImmutableList slot } + if (trackedPlayerOpen) { + cart?.onPlayerOpen() + } + addInventorySlots() } + override fun removed(p_38940_: Player) { + super.removed(p_38940_) + + if (trackedPlayerOpen) { + cart?.onPlayerClose() + } + } + override fun stillValid(player: Player): Boolean { return cart?.stillValid(player) ?: true }