diff --git a/src/main/java/ru/octol1ttle/flightassistant/alerts/impl/other/ElytraHealthLowAlert.java b/src/main/java/ru/octol1ttle/flightassistant/alerts/impl/other/ElytraHealthLowAlert.java index 54ff6d1..8fec55c 100644 --- a/src/main/java/ru/octol1ttle/flightassistant/alerts/impl/other/ElytraHealthLowAlert.java +++ b/src/main/java/ru/octol1ttle/flightassistant/alerts/impl/other/ElytraHealthLowAlert.java @@ -5,9 +5,9 @@ import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; import ru.octol1ttle.flightassistant.DrawHelper; -import ru.octol1ttle.flightassistant.alerts.impl.AlertSoundData; import ru.octol1ttle.flightassistant.alerts.api.BaseAlert; import ru.octol1ttle.flightassistant.alerts.api.IECAMAlert; +import ru.octol1ttle.flightassistant.alerts.impl.AlertSoundData; import ru.octol1ttle.flightassistant.computers.impl.AirDataComputer; import ru.octol1ttle.flightassistant.config.FAConfig; import ru.octol1ttle.flightassistant.config.IndicatorConfig; @@ -18,7 +18,7 @@ public class ElytraHealthLowAlert extends BaseAlert implements IECAMAlert { @Override public boolean isTriggered() { - return data.elytraHealth != null && data.elytraHealth.getInUnits(IndicatorConfig.ElytraHealthDisplayUnits.PERCENTAGE) <= 5.0f; + return data.elytraData != null && data.elytraData.getHealth(IndicatorConfig.ElytraHealthDisplayUnits.PERCENTAGE) <= 5.0f; } @Override @@ -31,4 +31,4 @@ public int render(TextRenderer textRenderer, DrawContext context, int x, int y, return DrawHelper.drawHighlightedText(textRenderer, context, Text.translatable("alerts.flightassistant.elytra_health_low"), x, y, FAConfig.indicator().warningColor, highlight && data.isFlying()); } -} \ No newline at end of file +} diff --git a/src/main/java/ru/octol1ttle/flightassistant/computers/impl/AirDataComputer.java b/src/main/java/ru/octol1ttle/flightassistant/computers/impl/AirDataComputer.java index 8258aa1..8bd4253 100644 --- a/src/main/java/ru/octol1ttle/flightassistant/computers/impl/AirDataComputer.java +++ b/src/main/java/ru/octol1ttle/flightassistant/computers/impl/AirDataComputer.java @@ -1,6 +1,5 @@ package ru.octol1ttle.flightassistant.computers.impl; -import com.google.common.collect.Iterables; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; @@ -40,7 +39,7 @@ public class AirDataComputer implements ITickableComputer { public float flightPitch; public float flightYaw; public float groundLevel; - public @Nullable ElytraHealth elytraHealth = null; + public @Nullable AirDataComputer.ElytraData elytraData = null; public boolean isCurrentChunkLoaded; public AirDataComputer(MinecraftClient mc) { @@ -56,7 +55,7 @@ public void tick() { groundLevel = computeGroundLevel(); flightPitch = computeFlightPitch(velocity, pitch()); flightYaw = computeFlightYaw(velocity, yaw()); - elytraHealth = computeElytraHealth(); + elytraData = computeElytraData(); } public boolean canAutomationsActivate() { @@ -113,10 +112,15 @@ private float computeFlightYaw(Vec3d velocity, float yaw) { return validate(FAMathHelper.toDegrees(Math.atan2(-velocity.x, velocity.z)), 180.0f); } - private ElytraHealth computeElytraHealth() { - for (ItemStack stack : Iterables.concat(player().getArmorItems(), player().getHandItems())) { + private ElytraData computeElytraData() { + for (ItemStack stack : player().getArmorItems()) { if (Items.ELYTRA.equals(stack.getItem())) { - return new ElytraHealth(stack.copy()); + return new ElytraData(stack.copy(), true); + } + } + for (ItemStack stack : player().getHandItems()) { + if (Items.ELYTRA.equals(stack.getItem())) { + return new ElytraData(stack.copy(), false); } } @@ -242,21 +246,23 @@ public void reset() { flightYaw = 0.0f; roll = 0.0f; groundLevel = 0; - elytraHealth = null; + elytraData = null; isCurrentChunkLoaded = true; } - public static class ElytraHealth { + public static class ElytraData { private final ItemStack stack; + private final boolean canFallFly; - public ElytraHealth(ItemStack stack) { + public ElytraData(ItemStack stack, boolean canFallFly) { if (!Items.ELYTRA.equals(stack.getItem())) { - throw new IllegalStateException("Attempted to initialize ElytraHealth, but the ItemStack does not contain an Elytra"); + throw new IllegalStateException("Attempted to initialize ElytraData, but the ItemStack does not contain an Elytra"); } this.stack = stack; + this.canFallFly = canFallFly; } - public float getInUnits(IndicatorConfig.ElytraHealthDisplayUnits units) { + public float getHealth(IndicatorConfig.ElytraHealthDisplayUnits units) { float remaining = (stack.getMaxDamage() - 1) - stack.getDamage(); return switch (units) { case REMAINING_DURABILITY -> validate(remaining, 0.0f, stack.getMaxDamage()); @@ -264,12 +270,12 @@ public float getInUnits(IndicatorConfig.ElytraHealthDisplayUnits units) { }; } - public Text format(IndicatorConfig.ElytraHealthDisplayUnits units) { + public Text formatHealth(IndicatorConfig.ElytraHealthDisplayUnits units) { if (!stack.isDamageable()) { return Text.translatable("short.flightassistant.infinite"); } - MutableText text = DrawHelper.asText("%s", MathHelper.ceil(getInUnits(units))); + MutableText text = DrawHelper.asText("%s", MathHelper.ceil(getHealth(units))); if (units == IndicatorConfig.ElytraHealthDisplayUnits.PERCENTAGE) { text.append("%"); } @@ -278,7 +284,7 @@ public Text format(IndicatorConfig.ElytraHealthDisplayUnits units) { } public boolean isUsable() { - return stack.getMaxDamage() - stack.getDamage() > 1; + return canFallFly && stack.getMaxDamage() - stack.getDamage() > 1; } } } diff --git a/src/main/java/ru/octol1ttle/flightassistant/computers/impl/safety/ElytraStateController.java b/src/main/java/ru/octol1ttle/flightassistant/computers/impl/safety/ElytraStateController.java index c541f9a..d3f9ec6 100644 --- a/src/main/java/ru/octol1ttle/flightassistant/computers/impl/safety/ElytraStateController.java +++ b/src/main/java/ru/octol1ttle/flightassistant/computers/impl/safety/ElytraStateController.java @@ -1,5 +1,6 @@ package ru.octol1ttle.flightassistant.computers.impl.safety; +import net.fabricmc.fabric.api.util.TriState; import net.minecraft.MinecraftVersion; import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket; import ru.octol1ttle.flightassistant.MinecraftProtocolVersions; @@ -10,15 +11,21 @@ public class ElytraStateController implements ITickableComputer { private final AirDataComputer data = ComputerRegistry.resolve(AirDataComputer.class); - private boolean syncedState; - private boolean changesPending; + private TriState syncedState; @Override public void tick() { - if (syncedState != data.isFlying() || data.player().isOnGround()) { - changesPending = false; + if (data.player().isOnGround()) { + syncedState = TriState.DEFAULT; + return; + } + if (syncedState != TriState.DEFAULT) { + if (syncedState.get() != data.isFlying()) { + syncedState = TriState.DEFAULT; + } + return; } - if (!isAvailable() || changesPending || !data.canAutomationsActivate(false)) { + if (!isAvailable() || !data.canAutomationsActivate(false)) { return; } @@ -28,7 +35,7 @@ public void tick() { } boolean flying = data.isFlying() || data.player().getAbilities().allowFlying; - boolean hasUsableElytra = data.elytraHealth != null && data.elytraHealth.isUsable(); + boolean hasUsableElytra = data.elytraData != null && data.elytraData.isUsable(); boolean notLookingToClutch = data.pitch() > -70.0f; boolean unsafeFallDistance = data.fallDistance() > 3.0f; if (FAConfig.computer().openElytraAutomatically && unsafeFallDistance && !flying && hasUsableElytra && notLookingToClutch) { @@ -38,9 +45,8 @@ public void tick() { } private void sendSwitchState() { - syncedState = data.isFlying(); + syncedState = TriState.of(data.isFlying()); data.player().networkHandler.sendPacket(new ClientCommandC2SPacket(data.player(), ClientCommandC2SPacket.Mode.START_FALL_FLYING)); - changesPending = true; } public static boolean isAvailable() { @@ -54,7 +60,6 @@ public String getFaultTextBaseKey() { @Override public void reset() { - syncedState = false; - changesPending = false; + syncedState = TriState.DEFAULT; } } diff --git a/src/main/java/ru/octol1ttle/flightassistant/hud/impl/ElytraHealthDisplay.java b/src/main/java/ru/octol1ttle/flightassistant/hud/impl/ElytraHealthDisplay.java index acb0ddb..fe6d784 100644 --- a/src/main/java/ru/octol1ttle/flightassistant/hud/impl/ElytraHealthDisplay.java +++ b/src/main/java/ru/octol1ttle/flightassistant/hud/impl/ElytraHealthDisplay.java @@ -26,9 +26,9 @@ public void render(DrawContext context, TextRenderer textRenderer) { int x = dim.xMid; int y = dim.bFrame; - if (FAConfig.indicator().showElytraHealth && data.elytraHealth != null) { + if (FAConfig.indicator().showElytraHealth && data.elytraData != null) { Color color; - float percentage = data.elytraHealth.getInUnits(IndicatorConfig.ElytraHealthDisplayUnits.PERCENTAGE); + float percentage = data.elytraData.getHealth(IndicatorConfig.ElytraHealthDisplayUnits.PERCENTAGE); if (percentage <= 5.0f) { color = FAConfig.indicator().warningColor; } else { @@ -37,7 +37,7 @@ public void render(DrawContext context, TextRenderer textRenderer) { DrawHelper.drawBorder(context, x - 3, y - 2, 30, color); DrawHelper.drawText(textRenderer, context, Text.translatable("short.flightassistant.elytra"), x - 10, y, color); - DrawHelper.drawText(textRenderer, context, data.elytraHealth.format(FAConfig.indicator().elytraHealthUnits), x, y, color); + DrawHelper.drawText(textRenderer, context, data.elytraData.formatHealth(FAConfig.indicator().elytraHealthUnits), x, y, color); } }