diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt index 4ecedb8c3..168b402a8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt @@ -18,14 +18,17 @@ import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger import kotlin.math.roundToInt class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) { - var strength: Int = 0 - set(value) { field = value.coerceIn(0 .. 3) } + var strength by synchronizer.int( + setter = setter@{ + value, access, _ -> access.write(value.coerceIn(0 .. 3)) + } + ) var speed: Int = 0 set(value) { field = value.coerceIn(0 .. 3) } private var ticksPassed = 0 - private var layers = 0 + var layers by synchronizer.int() override fun tickServer() { if (layers < strength + 1 && android.androidEnergy.extractEnergyExact(ENERGY_PER_LAYER, true)) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt index 2c5d49e64..21a3300ec 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt @@ -7,16 +7,13 @@ import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.item.ItemStack import net.minecraft.world.level.block.state.BlockState import net.minecraftforge.common.capabilities.ForgeCapabilities -import net.minecraftforge.energy.IEnergyStorage import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.energy import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.energyStoredMattery -import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.capability.maxEnergyStoredMattery -import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.capability.transcieveEnergy import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer @@ -53,94 +50,56 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte bottomDefault = ItemHandlerMode.INPUT_OUTPUT, ) + private var currentChangeSlot = 0 + private var currentDischangeSlot = 0 + init { savetable(::container, INVENTORY_KEY) + savetables.int(::currentChangeSlot) + savetables.int(::currentDischangeSlot) } private fun distributeEnergy(isReceiving: Boolean, howMuch: Decimal, simulate: Boolean): Decimal { if (!howMuch.isPositive) return Decimal.ZERO - val energies = ArrayList() + var summ = Decimal.ZERO + var remaining = howMuch + var currentSlot = if (isReceiving) currentChangeSlot else currentDischangeSlot + + for (i in 0 until container.containerSize - 1) { + val item = container[currentSlot] - for (item in container) { if (!item.isEmpty) { val energy = item.matteryEnergy ?: item.energy if (energy != null) { - energies.add(energy) + val diff = energy.transcieveEnergy(remaining, isReceiving, simulate) + summ += diff + remaining -= diff + + if (!remaining.isPositive) { + break + } } } + + currentSlot = (currentSlot + 1) % container.containerSize } - if (energies.isEmpty()) - return Decimal.ZERO - - if (howMuch.toInt() < energies.size || !energies.any { it is IMatteryEnergyStorage && it.transcieveEnergy(Decimal.ONE, isReceiving, true) == Decimal.ONE }) { - // sequential - var summ = Decimal.ZERO - var remaining = howMuch - - for (energy in energies) { - val diff = energy.transcieveEnergy(remaining, isReceiving, simulate) - summ += diff - remaining -= diff - - if (!remaining.isPositive) { - break - } - } - - if (!simulate && !summ.isZero) { - setChangedLight() - gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat() - } - - return summ - } else { - val distribution = Array(energies.size) { Decimal.ZERO } - var summ2 = Decimal.ZERO - - for ((i, energy) in energies.withIndex()) { - val diff = energy.transcieveEnergy(howMuch, isReceiving, simulate) - distribution[i] = diff - summ2 += distribution[i] - } - - if (summ2.isPositive) { - for (i in distribution.indices) { - distribution[i] = distribution[i] / summ2 - } - } else { - return Decimal.ZERO - } - - var summ = Decimal.ZERO - var remaining = howMuch - - for ((i, energy) in energies.withIndex()) { - val diff = energy.transcieveEnergy((howMuch * distribution[i]).coerceAtMost(remaining), isReceiving, simulate) - summ += diff - remaining -= diff - - if (!remaining.isPositive) { - break - } - } - - if (remaining.isPositive) { - val diff = energies.first { it is IMatteryEnergyStorage }.transcieveEnergy(remaining, isReceiving, simulate) - summ += diff - remaining -= diff - } - - if (!simulate && !summ.isZero) { - setChangedLight() - gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat() - } - - return summ + if (!simulate && !summ.isZero) { + setChangedLight() + gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat() } + + if (!simulate) { + if (isReceiving) + this.currentChangeSlot = currentSlot + else + this.currentDischangeSlot = currentSlot + } + + return summ } override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { @@ -151,6 +110,12 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte return distributeEnergy(isReceiving = true, howMuch, simulate) } + override fun tick() { + super.tick() + currentChangeSlot = (currentChangeSlot + 1) % container.containerSize + currentDischangeSlot = (currentDischangeSlot + 1) % container.containerSize + } + override val canSetBatteryLevel: Boolean get() = false diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt index 73e5a3a36..0d7607c15 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt @@ -16,6 +16,7 @@ import net.minecraftforge.client.event.ScreenEvent import net.minecraftforge.client.gui.overlay.ForgeGui import net.minecraftforge.client.gui.overlay.GuiOverlayManager import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability @@ -25,6 +26,7 @@ import ru.dbotthepony.mc.otm.config.ClientConfig import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.core.ifPresentK +import ru.dbotthepony.mc.otm.registry.AndroidFeatures import java.util.* import kotlin.math.ceil @@ -36,15 +38,16 @@ object MatteryGUI { val CHARGE_HUNGER = BARS.sprite(y = 18f, height = 9f) val CHARGE_HUNGER_BG = BARS.sprite(y = 27f, height = 9f) - private val BARS_HP = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/player_bars_health.png"), 81f, 54f) + private val BARS_HP = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/player_bars_health.png"), 81f, 63f) val HEALTH = BARS_HP.sprite(height = 9f) val HEALTH_BG = BARS_HP.sprite(y = 9f, height = 9f) + val HEALTH_BG_NANOBOTS = BARS_HP.sprite(y = 18f, height = 9f) - val HEALTH_POISON = BARS_HP.sprite(y = 18f, height = 9f) - val HEALTH_WITHER = BARS_HP.sprite(y = 27f, height = 9f) - val HEALTH_ABSORB = BARS_HP.sprite(y = 36f, height = 9f) - val HEALTH_FROZEN = BARS_HP.sprite(y = 45f, height = 9f) + val HEALTH_POISON = BARS_HP.sprite(y = 27f, height = 9f) + val HEALTH_WITHER = BARS_HP.sprite(y = 36f, height = 9f) + val HEALTH_ABSORB = BARS_HP.sprite(y = 45f, height = 9f) + val HEALTH_FROZEN = BARS_HP.sprite(y = 54f, height = 9f) private var originalBedButtonX = -1 private var originalBedButtonY = -1 @@ -308,8 +311,8 @@ object MatteryGUI { if (!gui.shouldDrawSurvivalElements()) return - val level: Float = (ply.health / ply.maxHealth).coerceIn(0.0f, 1.0f) - val levelAbsorb: Float = (ply.absorptionAmount / ply.maxHealth).coerceIn(0.0f, 1.0f) + val level: Float = (ply.health / ply.maxHealth).coerceIn(0.0f .. 1.0f) + val levelAbsorb: Float = (ply.absorptionAmount / ply.maxHealth).coerceIn(0.0f .. 1.0f) gui.setupOverlayRenderState(true, false) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f) @@ -321,6 +324,14 @@ object MatteryGUI { gui.leftHeight += 10 HEALTH_BG.render(event.poseStack, left.toFloat(), top.toFloat()) + + if (mattery.hasFeature(AndroidFeatures.NANOBOTS_ARMOR)) { + val featArmor = mattery.getFeature(AndroidFeatures.NANOBOTS_ARMOR) as NanobotsArmorFeature + val levelArmor: Float = (featArmor.layers.toFloat() / (featArmor.strength + 1).toFloat()).coerceIn(0.0f .. 1.0f) + + HEALTH_BG_NANOBOTS.renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(levelArmor * 81f)) + } + getSpriteForPlayer(ply).renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(level * 80f - 0.5f)) if (levelAbsorb > 0) { HEALTH_ABSORB.renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(levelAbsorb * 80f - 0.5f)) diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars_health.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars_health.png index abf4b1d3a..912697873 100644 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars_health.png and b/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars_health.png differ