134 lines
3.6 KiB
Kotlin
134 lines
3.6 KiB
Kotlin
package net.shadowfacts.phycon.block.redstone_emitter
|
|
|
|
import alexiil.mc.lib.attributes.item.GroupedItemInvView
|
|
import net.minecraft.item.ItemStack
|
|
import net.minecraft.nbt.CompoundTag
|
|
import net.minecraft.text.TranslatableText
|
|
import net.shadowfacts.phycon.api.packet.Packet
|
|
import net.shadowfacts.phycon.api.util.IPAddress
|
|
import net.shadowfacts.phycon.block.DeviceBlockEntity
|
|
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
|
import net.shadowfacts.phycon.init.PhyBlockEntities
|
|
import net.shadowfacts.phycon.packet.DeviceRemovedPacket
|
|
import net.shadowfacts.phycon.packet.ReadInventoryPacket
|
|
import net.shadowfacts.phycon.packet.RequestInventoryPacket
|
|
import net.shadowfacts.phycon.util.ClientConfigurableDevice
|
|
import net.shadowfacts.phycon.util.GhostInv
|
|
import kotlin.math.round
|
|
|
|
/**
|
|
* @author shadowfacts
|
|
*/
|
|
class RedstoneEmitterBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE_EMITTER),
|
|
ClientConfigurableDevice,
|
|
GhostInv {
|
|
|
|
private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInvView>()
|
|
var cachedEmittedPower: Int = 0
|
|
private set
|
|
|
|
var stackToMonitor: ItemStack = ItemStack.EMPTY
|
|
override var ghostSlotStack: ItemStack
|
|
get() = stackToMonitor
|
|
set(value) { stackToMonitor = value }
|
|
var maxAmount = 64
|
|
var mode = Mode.ANALOG
|
|
set(value) {
|
|
field = value
|
|
recalculateRedstone()
|
|
}
|
|
|
|
override fun handle(packet: Packet) {
|
|
when (packet) {
|
|
is ReadInventoryPacket -> handleReadInventory(packet)
|
|
is DeviceRemovedPacket -> handleDeviceRemoved(packet)
|
|
}
|
|
}
|
|
|
|
private fun handleReadInventory(packet: ReadInventoryPacket) {
|
|
inventoryCache[packet.source] = packet.inventory
|
|
recalculateRedstone()
|
|
}
|
|
|
|
private fun handleDeviceRemoved(packet: DeviceRemovedPacket) {
|
|
inventoryCache.remove(packet.source)
|
|
recalculateRedstone()
|
|
}
|
|
|
|
override fun tick() {
|
|
super.tick()
|
|
|
|
if (!world!!.isClient && counter % 20 == 0L) {
|
|
if (counter % 80 == 0L) {
|
|
updateInventories()
|
|
} else if (counter % 20 == 0L) {
|
|
recalculateRedstone()
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun updateInventories() {
|
|
sendPacket(RequestInventoryPacket(ipAddress))
|
|
}
|
|
|
|
private fun recalculateRedstone() {
|
|
if (world == null || world!!.isClient) return
|
|
|
|
if (stackToMonitor.isEmpty) {
|
|
cachedEmittedPower = 0
|
|
updateWorld()
|
|
return
|
|
}
|
|
val networkAmount = inventoryCache.values.fold(0) { acc, inv ->
|
|
acc + inv.getAmount(stackToMonitor)
|
|
}
|
|
cachedEmittedPower =
|
|
when (mode) {
|
|
Mode.ANALOG -> if (networkAmount == 0) {
|
|
0
|
|
} else {
|
|
1 + round(networkAmount / maxAmount.toDouble() * 14).toInt()
|
|
}
|
|
Mode.DIGITAL -> if (networkAmount >= maxAmount) 15 else 0
|
|
}
|
|
|
|
updateWorld()
|
|
}
|
|
|
|
private fun updateWorld() {
|
|
world!!.updateNeighborsAlways(pos, cachedState.block)
|
|
world!!.updateNeighborsAlways(pos.offset(cachedState[FaceDeviceBlock.FACING]), cachedState.block)
|
|
}
|
|
|
|
override fun toCommonTag(tag: CompoundTag) {
|
|
super.toCommonTag(tag)
|
|
tag.putInt("CachedEmittedPower", cachedEmittedPower)
|
|
tag.put("StackToMonitor", stackToMonitor.toTag(CompoundTag()))
|
|
writeDeviceConfiguration(tag)
|
|
}
|
|
|
|
override fun fromCommonTag(tag: CompoundTag) {
|
|
super.fromCommonTag(tag)
|
|
cachedEmittedPower = tag.getInt("CachedEmittedPower")
|
|
stackToMonitor = ItemStack.fromTag(tag.getCompound("StackToMonitor"))
|
|
loadDeviceConfiguration(tag)
|
|
}
|
|
|
|
override fun writeDeviceConfiguration(tag: CompoundTag) {
|
|
tag.putInt("MaxAmount", maxAmount)
|
|
tag.putString("Mode", mode.name)
|
|
}
|
|
|
|
override fun loadDeviceConfiguration(tag: CompoundTag) {
|
|
maxAmount = tag.getInt("MaxAmount")
|
|
mode = Mode.valueOf(tag.getString("Mode"))
|
|
}
|
|
|
|
enum class Mode {
|
|
ANALOG, DIGITAL;
|
|
|
|
val friendlyName = TranslatableText("gui.phycon.redstone_emitter_mode.${name.toLowerCase()}")
|
|
}
|
|
|
|
}
|