Update quantum battery item

This commit is contained in:
DBotThePony 2024-08-10 10:37:47 +07:00
parent ed8717964d
commit 23f02036b9
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 42 additions and 51 deletions

View File

@ -3,7 +3,8 @@ package ru.dbotthepony.mc.otm.item
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import net.minecraft.ChatFormatting
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.HolderLookup.Provider
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.FriendlyByteBuf
@ -15,16 +16,12 @@ import net.minecraft.world.item.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.saveddata.SavedData
import net.minecraftforge.client.event.ClientPlayerNetworkEvent
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.capabilities.ICapabilityProvider
import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.event.TickEvent
import net.minecraftforge.event.TickEvent.ServerTickEvent
import net.minecraftforge.registries.ForgeRegistries
import net.neoforged.neoforge.capabilities.Capabilities
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent
import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent
import net.neoforged.neoforge.event.tick.ServerTickEvent
import net.neoforged.neoforge.network.PacketDistributor
import net.neoforged.neoforge.network.handling.IPayloadContext
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.capability.FlowDirection
@ -38,8 +35,6 @@ import ru.dbotthepony.mc.otm.config.EnergyBalanceValues
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.getID
import ru.dbotthepony.mc.otm.core.getValue
import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.getDecimal
@ -48,16 +43,14 @@ import ru.dbotthepony.mc.otm.core.math.set
import ru.dbotthepony.mc.otm.core.math.writeDecimal
import ru.dbotthepony.mc.otm.core.nbt.getUUIDSafe
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.orThrow
import ru.dbotthepony.mc.otm.core.tagNotNull
import ru.dbotthepony.mc.otm.core.util.formatPower
import ru.dbotthepony.mc.otm.isClientThread
import ru.dbotthepony.mc.otm.isServerThread
import ru.dbotthepony.mc.otm.lazyPerServer
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener
import ru.dbotthepony.mc.otm.registry.MDataComponentTypes
import java.util.*
import java.util.function.Function
import java.util.function.Supplier
import kotlin.collections.MutableList
import kotlin.collections.component1
import kotlin.collections.component2
@ -65,7 +58,7 @@ import kotlin.collections.forEach
import kotlin.collections.iterator
import kotlin.collections.set
class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanceValues?) : Item(Properties().stacksTo(1).rarity(if (balanceValues == null) Rarity.EPIC else Rarity.UNCOMMON)), IQuantumLinked {
class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanceValues?) : Item(Properties().stacksTo(1).rarity(if (balanceValues == null) Rarity.EPIC else Rarity.UNCOMMON)), IQuantumLinked, CapabilitiesRegisterListener {
val isCreative = balanceValues == null
interface IValues {
@ -99,7 +92,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
}
class Data() : SavedData() {
constructor(nbt: CompoundTag) : this() {
constructor(nbt: CompoundTag, registry: Provider) : this() {
load(nbt)
}
@ -136,7 +129,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
return values(UUID.randomUUID())
}
override fun save(nbt: CompoundTag): CompoundTag {
override fun save(nbt: CompoundTag, registry: HolderLookup.Provider): CompoundTag {
for ((key, values) in data) {
nbt[key.toString()] = values.serialize()
}
@ -160,9 +153,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
it.overworld().dataStorage.computeIfAbsent(SavedData.Factory(::Data, ::Data, DataFixTypes.SAVED_DATA_MAP_DATA), "otm_$savedataID")
}
private inner class Power(private val stack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider {
private val resolver = LazyOptional.of { this }
private inner class Power(private val stack: ItemStack) : IMatteryEnergyStorage {
override val energyFlow: FlowDirection
get() = FlowDirection.BI_DIRECTIONAL
@ -170,23 +161,15 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
fun updateValues() {
if (!values.isServer && isServerThread()) {
values = serverData.values(stack.tag?.getUUIDSafe("uuid") ?: UUID.randomUUID().also { stack.tagNotNull["uuid"] = it })
values = serverData.values(stack[MDataComponentTypes.QUANTUM_LINK_ID] ?: UUID.randomUUID().also { stack[MDataComponentTypes.QUANTUM_LINK_ID] = it })
} else if (isClientThread()) {
val id = stack.tag?.getUUIDSafe("uuid") ?: return
val id = stack[MDataComponentTypes.QUANTUM_LINK_ID] ?: return
if (values.uuid != id)
values = clientData.computeIfAbsent(id, Function { UnboundValues(it) })
}
}
override fun <T : Any?> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (cap == ForgeCapabilities.ENERGY || cap == MatteryCapability.ENERGY) {
return resolver.cast()
}
return LazyOptional.empty()
}
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive)
return Decimal.ZERO
@ -296,14 +279,20 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
return p_150901_.matteryEnergy?.getBarColor() ?: super.getBarColor(p_150901_)
}
override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider {
return Power(stack)
override fun registerCapabilities(event: RegisterCapabilitiesEvent) {
event.registerItem(Capabilities.EnergyStorage.ITEM, { o, _ -> Power(o) }, this)
event.registerItem(MatteryCapability.ITEM_ENERGY, { o, _ -> Power(o) }, this)
}
override fun appendHoverText(itemStack: ItemStack, level: Level?, components: MutableList<Component>, flags: TooltipFlag) {
super.appendHoverText(itemStack, level, components, flags)
override fun appendHoverText(
itemStack: ItemStack,
context: TooltipContext,
components: MutableList<Component>,
flags: TooltipFlag
) {
super.appendHoverText(itemStack, context, components, flags)
val power = itemStack.getCapability(MatteryCapability.ENERGY).orThrow() as Power
val power = itemStack.getCapability(MatteryCapability.ITEM_ENERGY) as Power
power.updateValues()
components.add(TranslatableComponent("otm.item.quantum_description").withStyle(ChatFormatting.DARK_GRAY))
@ -328,12 +317,12 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
companion object {
fun clientDisconnect(event: ClientPlayerNetworkEvent.LoggingOut) {
ForgeRegistries.ITEMS.values.forEach { if (it is QuantumBatteryItem) it.clientData.clear() }
BuiltInRegistries.ITEM.forEach { if (it is QuantumBatteryItem) it.clientData.clear() }
}
fun readPacket(buff: FriendlyByteBuf): ChargePacket {
return ChargePacket(
ForgeRegistries.ITEMS.getValue(buff.readInt()) as QuantumBatteryItem,
BuiltInRegistries.ITEM.byId(buff.readInt()) as QuantumBatteryItem,
buff.readUUID(),
buff.readDecimal(),
buff.readDecimal(),
@ -341,17 +330,16 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
)
}
fun tick(event: ServerTickEvent) {
if (event.phase == TickEvent.Phase.END) {
for (ply in event.server.playerList.players) {
val networkedChannels = ObjectOpenHashSet<UUID>(0)
fun tick(event: ServerTickEvent.Post) {
for (ply in event.server.playerList.players) {
val networkedChannels = ObjectOpenHashSet<UUID>(0)
for (item in ply.trackedItems().filter { it.isNotEmpty && it.item is QuantumBatteryItem }) {
val power = item.getCapability(MatteryCapability.ENERGY).orThrow() as Power
power.updateValues()
if (power.values.isServer && networkedChannels.add(power.values.uuid)) {
GenericNetworkChannel.send(ply, ChargePacket(item.item as QuantumBatteryItem, power.values.uuid, power.batteryLevel, power.passed, power.received))
}
for (item in ply.trackedItems().filter { it.isNotEmpty && it.item is QuantumBatteryItem }) {
val power = item.getCapability(MatteryCapability.ITEM_ENERGY) as Power
power.updateValues()
if (power.values.isServer && networkedChannels.add(power.values.uuid)) {
PacketDistributor.sendToPlayer(ply, ChargePacket(item.item as QuantumBatteryItem, power.values.uuid, power.batteryLevel, power.passed, power.received))
}
}
}

View File

@ -41,6 +41,8 @@ object MDataComponentTypes {
}
}
private fun uuid() = DataComponentType.builder<UUID>().persistent(UUIDUtil.CODEC).networkSynchronized(UUIDUtil.STREAM_CODEC).build()
val BATTERY_LEVEL: DataComponentType<Decimal> by registry.register("battery_level") { DecimalComponent() }
val MAX_BATTERY_LEVEL: DataComponentType<Decimal> by registry.register("max_battery_level") { DecimalComponent() }
val MAX_BATTERY_INPUT: DataComponentType<Decimal> by registry.register("max_battery_input") { DecimalComponent() }
@ -48,8 +50,9 @@ object MDataComponentTypes {
val MATTER_LEVEL: DataComponentType<Decimal> by registry.register("matter_level") { DecimalComponent() }
val EXOPACK_SLOT_COUNT: DataComponentType<Int> by registry.register("exopack_slot_count") { DataComponentType.builder<Int>().persistent(Codec.INT).networkSynchronized(StreamCodecs.INT).build() }
val EXOPACK_UPGRADE_UUID: DataComponentType<UUID> by registry.register("exopack_upgrade_uuid") { DataComponentType.builder<UUID>().persistent(UUIDUtil.CODEC).networkSynchronized(UUIDUtil.STREAM_CODEC).build() }
val CONDENSATION_DRIVE_UUID: DataComponentType<UUID> by registry.register("condensation_drive_uuid") { DataComponentType.builder<UUID>().persistent(UUIDUtil.CODEC).networkSynchronized(UUIDUtil.STREAM_CODEC).build() }
val EXOPACK_UPGRADE_ID: DataComponentType<UUID> by registry.register("exopack_upgrade_id") { uuid() }
val QUANTUM_LINK_ID: DataComponentType<UUID> by registry.register("quantum_link_id") { uuid() }
val CONDENSATION_DRIVE_UUID: DataComponentType<UUID> by registry.register("condensation_drive_uuid") { uuid() }
val PATTERNS: DataComponentType<List<PatternState>> by registry.register("patterns") { DataComponentType.builder<List<PatternState>>().persistent(Codec.list(PatternState.CODEC)).build() }
val ITEM_FILTER: DataComponentType<ItemFilter> by registry.register("item_filter") { DataComponentType.builder<ItemFilter>().persistent(ItemFilter.CODEC).build() }