Iteration (death count) tracking as android

This commit is contained in:
DBotThePony 2022-08-28 22:22:10 +07:00
parent 5e890396ea
commit e395ffa2b5
Signed by: DBot
GPG Key ID: DCC23B5715498507
9 changed files with 223 additions and 17 deletions

View File

@ -4,13 +4,11 @@ import net.minecraft.core.Direction
import net.minecraft.data.recipes.ShapedRecipeBuilder import net.minecraft.data.recipes.ShapedRecipeBuilder
import net.minecraft.data.recipes.ShapelessRecipeBuilder import net.minecraft.data.recipes.ShapelessRecipeBuilder
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.IronBarsBlock import net.minecraft.world.level.block.IronBarsBlock
import net.minecraftforge.client.model.generators.ConfiguredModel import net.minecraftforge.client.model.generators.ConfiguredModel
import net.minecraftforge.client.model.generators.ModelFile import net.minecraftforge.client.model.generators.ModelFile
import net.minecraftforge.common.Tags import net.minecraftforge.common.Tags
import net.minecraftforge.common.loot.LootTableIdCondition
import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.Mod
import net.minecraftforge.data.event.GatherDataEvent import net.minecraftforge.data.event.GatherDataEvent
@ -20,7 +18,6 @@ import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
import ru.dbotthepony.mc.otm.data.LootTableBasicAppender
import ru.dbotthepony.mc.otm.datagen.blocks.BatteryBankProvider import ru.dbotthepony.mc.otm.datagen.blocks.BatteryBankProvider
import ru.dbotthepony.mc.otm.datagen.blocks.MatterBankProvider import ru.dbotthepony.mc.otm.datagen.blocks.MatterBankProvider
import ru.dbotthepony.mc.otm.datagen.blocks.MatteryBlockStateProvider import ru.dbotthepony.mc.otm.datagen.blocks.MatteryBlockStateProvider
@ -34,6 +31,7 @@ import ru.dbotthepony.mc.otm.datagen.recipes.MatteryRecipeProvider
import ru.dbotthepony.mc.otm.datagen.recipes.has import ru.dbotthepony.mc.otm.datagen.recipes.has
import ru.dbotthepony.mc.otm.registry.* import ru.dbotthepony.mc.otm.registry.*
import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.datagen.lang.MatteryLanguageProvider
import ru.dbotthepony.mc.otm.datagen.loot.addLootModifiers import ru.dbotthepony.mc.otm.datagen.loot.addLootModifiers
import ru.dbotthepony.mc.otm.datagen.recipes.addCraftingTableRecipes import ru.dbotthepony.mc.otm.datagen.recipes.addCraftingTableRecipes
import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock

View File

@ -1,6 +1,5 @@
package ru.dbotthepony.mc.otm.datagen.lang package ru.dbotthepony.mc.otm.datagen.lang
import ru.dbotthepony.mc.otm.datagen.MatteryLanguageProvider
import ru.dbotthepony.mc.otm.registry.* import ru.dbotthepony.mc.otm.registry.*
private fun decoratives(provider: MatteryLanguageProvider) { private fun decoratives(provider: MatteryLanguageProvider) {
@ -46,6 +45,7 @@ private fun sounds(provider: MatteryLanguageProvider) {
private fun misc(provider: MatteryLanguageProvider) { private fun misc(provider: MatteryLanguageProvider) {
with(provider.english) { with(provider.english) {
misc("iteration", "Iteration %s")
misc("death_reason", "Decommissioned!") misc("death_reason", "Decommissioned!")
misc("item.blackhole_immunity", "Negates gravitational effects of singularities") misc("item.blackhole_immunity", "Negates gravitational effects of singularities")

View File

@ -1,4 +1,4 @@
package ru.dbotthepony.mc.otm.datagen package ru.dbotthepony.mc.otm.datagen.lang
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap

View File

@ -115,5 +115,3 @@ fun ICapabilityProvider.getMatteryEnergySided(side: Direction? = null): LazyOpti
return getCapability(MatteryCapability.ENERGY, side) return getCapability(MatteryCapability.ENERGY, side)
} }
val LivingEntity.android get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()

View File

@ -14,7 +14,9 @@ import java.lang.Runnable
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraftforge.event.entity.living.LivingHurtEvent import net.minecraftforge.event.entity.living.LivingHurtEvent
import net.minecraft.nbt.ListTag import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.effect.MobEffect import net.minecraft.world.effect.MobEffect
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
@ -25,6 +27,7 @@ import net.minecraft.world.entity.player.Player
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.event.AttachCapabilitiesEvent import net.minecraftforge.event.AttachCapabilitiesEvent
import net.minecraftforge.event.entity.living.LivingDeathEvent
import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.event.entity.living.LivingEvent.LivingTickEvent import net.minecraftforge.event.entity.living.LivingEvent.LivingTickEvent
import net.minecraftforge.event.entity.player.PlayerEvent import net.minecraftforge.event.entity.player.PlayerEvent
@ -39,9 +42,18 @@ import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.registry.StatNames import ru.dbotthepony.mc.otm.registry.StatNames
import java.util.* import java.util.*
import kotlin.collections.ArrayDeque
@Suppress("unused") @Suppress("unused")
class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEnergyStorage, INBTSerializable<CompoundTag> { class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
private var shouldSendIteration = false
var iteration = 0
private set
private var lastDeathTick = 0
private val deathLog = ArrayDeque<Pair<Int, Component>>()
private var battery = ImpreciseFraction.ZERO private var battery = ImpreciseFraction.ZERO
private var maxBattery = ImpreciseFraction(60000) private var maxBattery = ImpreciseFraction(60000)
@ -85,6 +97,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
isAndroid = true isAndroid = true
willBecomeAndroid = false willBecomeAndroid = false
shouldPlaySound = false shouldPlaySound = false
iteration = 0
deathLog.clear()
battery = ImpreciseFraction(60000) battery = ImpreciseFraction(60000)
maxBattery = ImpreciseFraction(60000) maxBattery = ImpreciseFraction(60000)
} }
@ -102,6 +116,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
isAndroid = false isAndroid = false
shouldPlaySound = false shouldPlaySound = false
iteration = 0
deathLog.clear()
battery = ImpreciseFraction(0) battery = ImpreciseFraction(0)
maxBattery = ImpreciseFraction(60000) maxBattery = ImpreciseFraction(60000)
dropBattery() dropBattery()
@ -116,20 +132,24 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
} }
fun obliviate(refund: Boolean = true) { fun obliviate(refund: Boolean = true) {
if (refund) {
for (instance in research.values) { for (instance in research.values) {
if (instance.isResearched) { if (instance.isResearched) {
instance.unResearch() instance.unResearch()
if (refund) {
instance.refund(simulate = false) instance.refund(simulate = false)
} }
} }
} }
val copy = java.util.List.copyOf(features.values) val copy = ArrayList<AndroidFeature>(features.values.size).also { it.addAll(features.values) }
for (feature in copy) { for (feature in copy) {
removeFeature(feature.type) removeFeature(feature.type)
} }
iteration = 0
deathLog.clear()
} }
fun <T : AndroidResearch> getResearch(type: AndroidResearchType<T>): T { fun <T : AndroidResearch> getResearch(type: AndroidResearchType<T>): T {
@ -260,10 +280,36 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
tag["research"] = list tag["research"] = list
tag["iteration"] = iteration
tag["should_send_iteration"] = shouldSendIteration
tag["death_log"] = ListTag().also {
for ((ticks, component) in deathLog) {
it.add(CompoundTag().also {
it["ticks"] = ticks
it["component"] = StringTag.valueOf(Component.Serializer.toJson(component))
})
}
}
return tag return tag
} }
override fun deserializeNBT(compound: CompoundTag) { override fun deserializeNBT(compound: CompoundTag) {
iteration = compound.getInt("iteration")
shouldSendIteration = compound.getBoolean("should_send_iteration")
deathLog.clear()
for (value in compound.getList("death_log", Tag.TAG_COMPOUND.toInt())) {
value as CompoundTag
val component = Component.Serializer.fromJson(value.getString("component"))
if (component != null) {
deathLog.add(value.getInt("ticks") to component)
}
}
compound.ifHas("energy_stored") { compound.ifHas("energy_stored") {
battery = ImpreciseFraction.deserializeNBT(it) battery = ImpreciseFraction.deserializeNBT(it)
} }
@ -502,6 +548,11 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
sendNetwork(AndroidFeatureSyncPacket(instance)) sendNetwork(AndroidFeatureSyncPacket(instance))
} }
} }
if (shouldSendIteration) {
sendNetwork(PlayerIterationPacket(iteration, deathLog))
shouldSendIteration = false
}
} }
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
@ -669,7 +720,9 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
@SubscribeEvent(priority = EventPriority.LOWEST) @SubscribeEvent(priority = EventPriority.LOWEST)
fun onHurtEvent(event: LivingHurtEvent) { fun onHurtEvent(event: LivingHurtEvent) {
if (event.isCanceled) return if (event.isCanceled) {
return
}
event.entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { it.onHurt(event) } event.entity.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { it.onHurt(event) }
} }
@ -692,9 +745,37 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
.ifPresentK { it.invalidateNetworkState() } .ifPresentK { it.invalidateNetworkState() }
} }
@SubscribeEvent(priority = EventPriority.LOWEST)
fun onPlayerDeath(event: LivingDeathEvent) {
if (event.isCanceled) {
return
}
val ply = event.entity as? Player ?: return
val mattery = ply.matteryPlayer ?: return
if (mattery.lastDeathTick != ply.tickCount) {
mattery.lastDeathTick = ply.tickCount
} else {
return
}
if (!mattery.isAndroid) {
return
}
mattery.iteration++
mattery.shouldSendIteration = true
mattery.deathLog.addLast(ply.tickCount to ply.combatTracker.deathMessage)
while (mattery.deathLog.size > 6) {
mattery.deathLog.removeFirst()
}
}
@SubscribeEvent @SubscribeEvent
fun onPlayerCloneEvent(event: PlayerEvent.Clone) { fun onPlayerCloneEvent(event: PlayerEvent.Clone) {
val it = event.entity.android ?: return val it = event.entity.matteryPlayer ?: return
var resolver = event.original.getCapability(MatteryCapability.MATTERY_PLAYER) var resolver = event.original.getCapability(MatteryCapability.MATTERY_PLAYER)
@ -725,4 +806,4 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
} }
} }
val ICapabilityProvider.matteryPlayer get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull() val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()

View File

@ -5,10 +5,12 @@ import net.minecraft.client.gui.components.Button
import net.minecraft.client.gui.screens.DeathScreen import net.minecraft.client.gui.screens.DeathScreen
import net.minecraft.client.gui.screens.InBedChatScreen import net.minecraft.client.gui.screens.InBedChatScreen
import net.minecraft.client.player.LocalPlayer import net.minecraft.client.player.LocalPlayer
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.effect.MobEffects import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraftforge.client.event.RenderGuiEvent
import net.minecraftforge.client.event.RenderGuiOverlayEvent import net.minecraftforge.client.event.RenderGuiOverlayEvent
import net.minecraftforge.client.event.ScreenEvent import net.minecraftforge.client.event.ScreenEvent
import net.minecraftforge.client.gui.overlay.ForgeGui import net.minecraftforge.client.gui.overlay.ForgeGui
@ -16,10 +18,13 @@ import net.minecraftforge.client.gui.overlay.GuiOverlayManager
import net.minecraftforge.eventbus.api.EventPriority import net.minecraftforge.eventbus.api.EventPriority
import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.eventbus.api.SubscribeEvent
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.TextComponent
import ru.dbotthepony.mc.otm.TranslatableComponent import ru.dbotthepony.mc.otm.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.core.RGBAColor
import ru.dbotthepony.mc.otm.ifPresentK import ru.dbotthepony.mc.otm.ifPresentK
import java.util.* import java.util.*
@ -36,6 +41,7 @@ object MatteryGUI {
private val button_shaker = Random() private val button_shaker = Random()
@SubscribeEvent @SubscribeEvent
@Suppress("unused")
fun onScreenRender(event: ScreenEvent.Render.Pre) { fun onScreenRender(event: ScreenEvent.Render.Pre) {
if (knownButtonScreen != null && knownButton == null) { if (knownButtonScreen != null && knownButton == null) {
for (widget in knownButtonScreen!!.renderables) { for (widget in knownButtonScreen!!.renderables) {
@ -83,6 +89,7 @@ object MatteryGUI {
} }
@SubscribeEvent(priority = EventPriority.LOWEST) @SubscribeEvent(priority = EventPriority.LOWEST)
@Suppress("unused")
fun onOpenGUIEvent(event: ScreenEvent.Opening) { fun onOpenGUIEvent(event: ScreenEvent.Opening) {
knownButtonX = -1 knownButtonX = -1
knownButtonY = -1 knownButtonY = -1
@ -118,7 +125,87 @@ object MatteryGUI {
GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "air_level")) GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "air_level"))
} }
var iteration = 0
var showIterationUntil = 0L
var showIterationUntilFade = 0L
val deathLog = ArrayList<Pair<Int, Component>>()
fun showIteration(event: RenderGuiEvent.Post) {
if (minecraft.player?.matteryPlayer?.isAndroid != true) {
return
}
val time = System.currentTimeMillis()
if (time > showIterationUntilFade) {
return
}
val stack = event.poseStack
val window = event.window
stack.pushPose()
val negateScale = 1f / window.guiScale.toFloat()
var modifyScale = 6f * negateScale
val finalScale = modifyScale * window.guiScale.toFloat()
stack.scale(modifyScale, modifyScale, modifyScale)
var width = window.guiScaledWidth / modifyScale
var height = window.guiScaledHeight / modifyScale
var x = width / 2f
var y = height / 2f
val progress = if (time < showIterationUntil) 1f else 1f - (time - showIterationUntil).toFloat() / (showIterationUntilFade - showIterationUntil).toFloat()
val scissorBase = (y - 12f) * finalScale
val scissorHeight = (12f + (deathLog.size - 2f).coerceAtLeast(0f) * minecraft.font.lineHeight * modifyScale * 0.0875f) * finalScale
pushScissorRect(0, (scissorBase + scissorHeight * (1f - progress)).toInt(), window.width, (scissorHeight * progress * 2f).toInt())
setDrawColor(RGBAColor(1f, 1f, 1f, 0.4f))
drawRect(stack, 0f, y - 12f, window.guiScaledWidth.toFloat(), 24f + (deathLog.size - 2f).coerceAtLeast(0f) * minecraft.font.lineHeight * modifyScale * 0.175f)
val text = TranslatableComponent("otm.iteration", iteration)
minecraft.font.drawAligned(stack, text, TextAlign.CENTER_CENTER, x + 1f, y + 1f, RGBAColor.BLACK)
minecraft.font.drawAligned(stack, text, TextAlign.CENTER_CENTER, x, y, RGBAColor.WHITE)
stack.scale(0.35f, 0.35f, 0.35f)
modifyScale *= 0.35f
width = window.guiScaledWidth / modifyScale
height = window.guiScaledHeight / modifyScale
x = width / 2f
y = height / 2f + minecraft.font.lineHeight * finalScale * 0.35f
var color = 0xFF
for (component in deathLog) {
minecraft.font.drawAligned(stack, component.second, TextAlign.CENTER_CENTER, x + 1f, y + 1f, RGBAColor.BLACK)
minecraft.font.drawAligned(stack, component.second, TextAlign.CENTER_CENTER, x, y, RGBAColor(color, color, color))
y += minecraft.font.lineHeight
color = (color - 0x20).coerceAtLeast(0x0)
}
stack.popPose()
popScissorRect()
}
@SubscribeEvent
@Suppress("unused")
fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
showIteration(event)
}
@SubscribeEvent(priority = EventPriority.HIGH) @SubscribeEvent(priority = EventPriority.HIGH)
@Suppress("unused")
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) { fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) { if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) {
return return

View File

@ -15,6 +15,7 @@ import ru.dbotthepony.mc.otm.TranslatableComponent
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.* import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.registry.MItems import ru.dbotthepony.mc.otm.registry.MItems
@ -143,7 +144,7 @@ class BlackHoleRenderer(private val context: BlockEntityRendererProvider.Context
RenderSystem.enableCull() RenderSystem.enableCull()
} }
if (!Minecraft.getInstance().options.hideGui && ( if (!minecraft.options.hideGui && (
(ply.mainHandItem.item == MItems.BLACK_HOLE_SCANNER || ply.offhandItem.item == MItems.BLACK_HOLE_SCANNER) && (ply.mainHandItem.item == MItems.BLACK_HOLE_SCANNER || ply.offhandItem.item == MItems.BLACK_HOLE_SCANNER) &&
poseStack.translation().length() < tile.gravitationStrength * 64.0 || poseStack.translation().length() < tile.gravitationStrength * 64.0 ||
(ply.abilities.instabuild || ply.matteryPlayer?.isAndroid == true) && (ply.abilities.instabuild || ply.matteryPlayer?.isAndroid == true) &&

View File

@ -67,7 +67,7 @@ class EnergySwordItem : Item(Properties().stacksTo(1).rarity(Rarity.RARE).tab(Ov
override fun hurtEnemy(itemStack: ItemStack, victim: LivingEntity, attacker: LivingEntity): Boolean { override fun hurtEnemy(itemStack: ItemStack, victim: LivingEntity, attacker: LivingEntity): Boolean {
itemStack.getCapability(MatteryCapability.ENERGY).orNull()?.let { itemStack.getCapability(MatteryCapability.ENERGY).orNull()?.let {
if (!it.extractEnergyInnerExact(ENERGY_PER_SWING, false).isZero) { if (!it.extractEnergyInnerExact(ENERGY_PER_SWING, false).isZero) {
victim.android?.let { victim.matteryPlayer?.let {
it.extractEnergyInner(ENERGY_ZAP, false) it.extractEnergyInner(ENERGY_ZAP, false)
victim.hurt(EMPDamageSource(attacker), 8f) victim.hurt(EMPDamageSource(attacker), 8f)
} }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.network
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT
import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER
@ -12,6 +13,7 @@ import ru.dbotthepony.mc.otm.android.AndroidResearch
import ru.dbotthepony.mc.otm.android.AndroidResearchType import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.MatteryGUI
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.readImpreciseFraction import ru.dbotthepony.mc.otm.core.readImpreciseFraction
@ -222,6 +224,43 @@ class AndroidEnergyLevelPacket(val level: ImpreciseFraction, val isMaxEnergy: Bo
} }
} }
class PlayerIterationPacket(val iteration: Int, val deathLog: List<Pair<Int, Component>>) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeInt(iteration)
buff.writeInt(deathLog.size)
for ((ticks, value) in deathLog) {
buff.writeInt(ticks)
buff.writeComponent(value)
}
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
MatteryGUI.iteration = iteration
MatteryGUI.deathLog.clear()
MatteryGUI.deathLog.addAll(deathLog)
MatteryGUI.showIterationUntil = System.currentTimeMillis() + 4000L
MatteryGUI.showIterationUntilFade = System.currentTimeMillis() + 5000L
}
companion object {
fun read(buff: FriendlyByteBuf): PlayerIterationPacket {
val iteration = buff.readInt()
val size = buff.readInt()
val list = ArrayList<Pair<Int, Component>>()
for (i in 0 until size) {
list.add(buff.readInt() to buff.readComponent())
}
return PlayerIterationPacket(iteration, list)
}
}
}
object MatteryPlayerNetworkChannel : MatteryNetworkChannel( object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
version = "1", version = "1",
name = "player" name = "player"
@ -238,5 +277,7 @@ object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
add(AndroidFeatureRemovePacket::class.java, AndroidFeatureRemovePacket.Companion::read, PLAY_TO_CLIENT) add(AndroidFeatureRemovePacket::class.java, AndroidFeatureRemovePacket.Companion::read, PLAY_TO_CLIENT)
add(AndroidBatteryItemPacket::class.java, AndroidBatteryItemPacket.Companion::read, PLAY_TO_CLIENT) add(AndroidBatteryItemPacket::class.java, AndroidBatteryItemPacket.Companion::read, PLAY_TO_CLIENT)
add(AndroidEnergyLevelPacket::class.java, AndroidEnergyLevelPacket.Companion::read, PLAY_TO_CLIENT) add(AndroidEnergyLevelPacket::class.java, AndroidEnergyLevelPacket.Companion::read, PLAY_TO_CLIENT)
add(PlayerIterationPacket::class.java, PlayerIterationPacket.Companion::read, PLAY_TO_CLIENT)
} }
} }