Quantum battery now display power level on client
This commit is contained in:
parent
cbea8873e9
commit
a9d78fc31a
@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
|
|||||||
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
|
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
|
||||||
|
import ru.dbotthepony.mc.otm.item.QuantumBatteryItem;
|
||||||
import ru.dbotthepony.mc.otm.item.weapon.AbstractWeaponItem;
|
import ru.dbotthepony.mc.otm.item.weapon.AbstractWeaponItem;
|
||||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem;
|
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem;
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterDataKt;
|
import ru.dbotthepony.mc.otm.matter.MatterDataKt;
|
||||||
@ -88,6 +89,7 @@ public final class OverdriveThatMatters {
|
|||||||
MinecraftForge.EVENT_BUS.register(MatterDataKt.class);
|
MinecraftForge.EVENT_BUS.register(MatterDataKt.class);
|
||||||
MinecraftForge.EVENT_BUS.register(ExplosionQueue.Companion);
|
MinecraftForge.EVENT_BUS.register(ExplosionQueue.Companion);
|
||||||
MinecraftForge.EVENT_BUS.register(AbstractWeaponItem.Companion);
|
MinecraftForge.EVENT_BUS.register(AbstractWeaponItem.Companion);
|
||||||
|
MinecraftForge.EVENT_BUS.addListener(QuantumBatteryItem.Companion::tick);
|
||||||
|
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().register(MatteryCapability.class);
|
FMLJavaModLoadingContext.get().getModEventBus().register(MatteryCapability.class);
|
||||||
|
|
||||||
@ -105,6 +107,7 @@ public final class OverdriveThatMatters {
|
|||||||
WeaponNetworkChannel.INSTANCE.register();
|
WeaponNetworkChannel.INSTANCE.register();
|
||||||
RegistryNetworkChannel.INSTANCE.register();
|
RegistryNetworkChannel.INSTANCE.register();
|
||||||
WorldNetworkChannel.INSTANCE.register();
|
WorldNetworkChannel.INSTANCE.register();
|
||||||
|
GenericNetworkChannel.INSTANCE.register();
|
||||||
|
|
||||||
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
|
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
|
||||||
|
|
||||||
|
@ -118,6 +118,8 @@ private var _server: MinecraftServer? = null
|
|||||||
private var _serverThread: Thread? = null
|
private var _serverThread: Thread? = null
|
||||||
private var _clientThread: Thread? = null
|
private var _clientThread: Thread? = null
|
||||||
|
|
||||||
|
val isClient: Boolean get() = _clientThread !== null
|
||||||
|
|
||||||
fun recordClientThread() {
|
fun recordClientThread() {
|
||||||
if (_clientThread != null) {
|
if (_clientThread != null) {
|
||||||
throw IllegalStateException("Already have client channel")
|
throw IllegalStateException("Already have client channel")
|
||||||
@ -127,13 +129,13 @@ fun recordClientThread() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun runIfClient(lambda: () -> Unit) {
|
fun runIfClient(lambda: () -> Unit) {
|
||||||
if (_clientThread !== null) {
|
if (isClient) {
|
||||||
lambda.invoke()
|
lambda.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <V> runIfClient(value: V, lambda: () -> V): V {
|
fun <V> runIfClient(value: V, lambda: () -> V): V {
|
||||||
if (_clientThread !== null) {
|
if (isClient) {
|
||||||
return lambda.invoke()
|
return lambda.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.container
|
||||||
|
|
||||||
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
|
||||||
|
class ContainerIterator(private val container: Container) : MutableIterator<ItemStack> {
|
||||||
|
private var index = 0
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return index < container.containerSize
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): ItemStack {
|
||||||
|
if (index >= container.containerSize) {
|
||||||
|
throw IllegalStateException("Already finished iterating")
|
||||||
|
}
|
||||||
|
|
||||||
|
return container[index++]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
if (index == 0) {
|
||||||
|
throw IllegalStateException("Never called next()")
|
||||||
|
}
|
||||||
|
|
||||||
|
container[index - 1] = ItemStack.EMPTY
|
||||||
|
}
|
||||||
|
}
|
@ -6,30 +6,6 @@ import net.minecraftforge.common.capabilities.Capability
|
|||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||||
|
|
||||||
class ContainerIterator(private val container: Container) : MutableIterator<ItemStack> {
|
|
||||||
private var index = 0
|
|
||||||
|
|
||||||
override fun hasNext(): Boolean {
|
|
||||||
return index < container.containerSize
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun next(): ItemStack {
|
|
||||||
if (index >= container.containerSize) {
|
|
||||||
throw IllegalStateException("Already finished iterating")
|
|
||||||
}
|
|
||||||
|
|
||||||
return container[index++]
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun remove() {
|
|
||||||
if (index == 0) {
|
|
||||||
throw IllegalStateException("Never called next()")
|
|
||||||
}
|
|
||||||
|
|
||||||
container[index - 1] = ItemStack.EMPTY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class NonEmptyItemStackIterator(protected open val parent: Iterator<ItemStack>) : Iterator<ItemStack> {
|
open class NonEmptyItemStackIterator(protected open val parent: Iterator<ItemStack>) : Iterator<ItemStack> {
|
||||||
private var itemStack: ItemStack? = null
|
private var itemStack: ItemStack? = null
|
||||||
private var searched = false
|
private var searched = false
|
||||||
|
30
src/main/kotlin/ru/dbotthepony/mc/otm/core/MenuIterator.kt
Normal file
30
src/main/kotlin/ru/dbotthepony/mc/otm/core/MenuIterator.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core
|
||||||
|
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
|
||||||
|
class MenuIterator(private val menu: AbstractContainerMenu) : MutableIterator<ItemStack> {
|
||||||
|
private var index = 0
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return index < menu.slots.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): ItemStack {
|
||||||
|
if (index >= menu.slots.size) {
|
||||||
|
throw IllegalStateException("Already finished iterating")
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu.slots[index++].item
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
if (index == 0) {
|
||||||
|
throw IllegalStateException("Never called next()")
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.slots[index - 1].set(ItemStack.EMPTY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AbstractContainerMenu.itemStackIterator() : MutableIterator<ItemStack> = MenuIterator(this)
|
@ -1,24 +1,35 @@
|
|||||||
package ru.dbotthepony.mc.otm.item
|
package ru.dbotthepony.mc.otm.item
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.*
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.item.Rarity
|
|
||||||
import net.minecraft.world.item.TooltipFlag
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
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.capabilities.ICapabilityProvider
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import net.minecraftforge.event.TickEvent
|
||||||
|
import net.minecraftforge.event.TickEvent.ServerTickEvent
|
||||||
|
import net.minecraftforge.network.NetworkEvent
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
|
import net.minecraftforge.registries.ForgeRegistry
|
||||||
import ru.dbotthepony.mc.otm.*
|
import ru.dbotthepony.mc.otm.*
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.core.itemStackIterator
|
||||||
|
import ru.dbotthepony.mc.otm.container.nonEmpty
|
||||||
import ru.dbotthepony.mc.otm.core.*
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
|
import ru.dbotthepony.mc.otm.network.GenericNetworkChannel
|
||||||
|
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||||
|
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||||
import ru.dbotthepony.mc.otm.saveddata.SavedCountingMap
|
import ru.dbotthepony.mc.otm.saveddata.SavedCountingMap
|
||||||
import ru.dbotthepony.mc.otm.saveddata.SavedMapDelegate
|
import ru.dbotthepony.mc.otm.saveddata.SavedMapDelegate
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
class QuantumBatteryItem : Item {
|
class QuantumBatteryItem : Item {
|
||||||
private inner class Power(private val stack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider {
|
private inner class Power(private val stack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider {
|
||||||
@ -112,6 +123,10 @@ class QuantumBatteryItem : Item {
|
|||||||
determineQuantumLink()
|
determineQuantumLink()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isClientThread()) {
|
||||||
|
return clientPowerMap[delegate.index] ?: delegate.value
|
||||||
|
}
|
||||||
|
|
||||||
return delegate.value
|
return delegate.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +157,23 @@ class QuantumBatteryItem : Item {
|
|||||||
delegate = saveData?.computeIfAbsent(existing) ?: SavedMapDelegate(null, existing, delegate.value)
|
delegate = saveData?.computeIfAbsent(existing) ?: SavedMapDelegate(null, existing, delegate.value)
|
||||||
}
|
}
|
||||||
} else if (!isServerThread()) {
|
} else if (!isServerThread()) {
|
||||||
// client
|
// client ?
|
||||||
|
val existing = stack.tag?.getInt("link_id") ?: return
|
||||||
|
|
||||||
|
if (existing != delegate.index) {
|
||||||
|
delegate = SavedMapDelegate(delegate.parent, existing, delegate.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun determineQuantumLinkWeak() {
|
||||||
|
if (delegate.parent == null && isServerThread()) {
|
||||||
|
val existing = stack.tag?.getInt("link_id")
|
||||||
|
|
||||||
|
if (existing != null) {
|
||||||
|
delegate = saveData?.computeIfAbsent(existing) ?: SavedMapDelegate(null, existing, delegate.value)
|
||||||
|
}
|
||||||
|
} else if (!isServerThread()) {
|
||||||
val existing = stack.tag?.getInt("link_id") ?: return
|
val existing = stack.tag?.getInt("link_id") ?: return
|
||||||
|
|
||||||
if (existing != delegate.index) {
|
if (existing != delegate.index) {
|
||||||
@ -170,6 +201,11 @@ class QuantumBatteryItem : Item {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val clientPowerMap: Int2ObjectAVLTreeMap<ImpreciseFraction> by lazy {
|
||||||
|
check(isClient) { "Invalid side" }
|
||||||
|
Int2ObjectAVLTreeMap()
|
||||||
|
}
|
||||||
|
|
||||||
constructor(saveDataID: String) : super(Properties().stacksTo(1).rarity(Rarity.EPIC).tab(OverdriveThatMatters.INSTANCE.CREATIVE_TAB)) {
|
constructor(saveDataID: String) : super(Properties().stacksTo(1).rarity(Rarity.EPIC).tab(OverdriveThatMatters.INSTANCE.CREATIVE_TAB)) {
|
||||||
isCreative = true
|
isCreative = true
|
||||||
capacity = null
|
capacity = null
|
||||||
@ -216,4 +252,51 @@ class QuantumBatteryItem : Item {
|
|||||||
|
|
||||||
components.add(TranslatableComponent("otm.item.quantum_link_id", power.delegate.index).withStyle(ChatFormatting.DARK_GRAY))
|
components.add(TranslatableComponent("otm.item.quantum_link_id", power.delegate.index).withStyle(ChatFormatting.DARK_GRAY))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun readPacket(buff: FriendlyByteBuf): ChargePacket {
|
||||||
|
return ChargePacket(
|
||||||
|
(ForgeRegistries.ITEMS as ForgeRegistry<Item>).getValue(buff.readInt()) as QuantumBatteryItem,
|
||||||
|
buff.readInt(),
|
||||||
|
buff.readImpreciseFraction()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tick(event: ServerTickEvent) {
|
||||||
|
if (event.phase == TickEvent.Phase.END) {
|
||||||
|
for (ply in event.server.playerList.players) {
|
||||||
|
val networkedChannels = IntAVLTreeSet()
|
||||||
|
|
||||||
|
for (item in ply.containerMenu.itemStackIterator().nonEmpty()) {
|
||||||
|
if (item.item is QuantumBatteryItem) {
|
||||||
|
val power = item.getCapability(MatteryCapability.ENERGY).orThrow() as Power
|
||||||
|
|
||||||
|
power.determineQuantumLinkWeak()
|
||||||
|
|
||||||
|
if (power.delegate.index < 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (networkedChannels.add(power.delegate.index)) {
|
||||||
|
GenericNetworkChannel.send(ply, ChargePacket(item.item as QuantumBatteryItem, power.delegate.index, power.batteryLevel))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChargePacket(val type: QuantumBatteryItem, val channel: Int, val value: ImpreciseFraction) : MatteryPacket {
|
||||||
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeInt((ForgeRegistries.ITEMS as ForgeRegistry<Item>).getID(type))
|
||||||
|
buff.writeInt(channel)
|
||||||
|
buff.writeImpreciseFraction(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
context.packetHandled = true
|
||||||
|
type.clientPowerMap[channel] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.network
|
||||||
|
|
||||||
|
import net.minecraftforge.network.NetworkDirection
|
||||||
|
import ru.dbotthepony.mc.otm.item.QuantumBatteryItem
|
||||||
|
|
||||||
|
object GenericNetworkChannel : MatteryNetworkChannel(
|
||||||
|
version = "1",
|
||||||
|
name = "generic"
|
||||||
|
) {
|
||||||
|
fun register() {
|
||||||
|
add(QuantumBatteryItem.ChargePacket::class.java, QuantumBatteryItem.Companion::readPacket, NetworkDirection.PLAY_TO_CLIENT)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user