Add next death text
This commit is contained in:
@@ -11,6 +11,7 @@ import net.respawnbackoff.CooldownSyncPayload;
|
|||||||
public class RespawnBackoffClient implements ClientModInitializer {
|
public class RespawnBackoffClient implements ClientModInitializer {
|
||||||
private static volatile boolean overlayActive;
|
private static volatile boolean overlayActive;
|
||||||
private static volatile long cooldownEndEpochMs;
|
private static volatile long cooldownEndEpochMs;
|
||||||
|
private static volatile long nextDeathWaitMinutes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
@@ -20,6 +21,7 @@ public class RespawnBackoffClient implements ClientModInitializer {
|
|||||||
context.client().execute(() -> {
|
context.client().execute(() -> {
|
||||||
overlayActive = payload.active();
|
overlayActive = payload.active();
|
||||||
cooldownEndEpochMs = payload.cooldownEndEpochMs();
|
cooldownEndEpochMs = payload.cooldownEndEpochMs();
|
||||||
|
nextDeathWaitMinutes = payload.nextDeathWaitMinutes();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -44,13 +46,23 @@ public class RespawnBackoffClient implements ClientModInitializer {
|
|||||||
int seconds = totalSeconds % 60;
|
int seconds = totalSeconds % 60;
|
||||||
String time = String.format("%02d:%02d", minutes, seconds);
|
String time = String.format("%02d:%02d", minutes, seconds);
|
||||||
Component line = Component.translatable("respawn_backoff.hud.countdown", time);
|
Component line = Component.translatable("respawn_backoff.hud.countdown", time);
|
||||||
|
int lineHeight = client.font.lineHeight;
|
||||||
|
int centerY = h / 2;
|
||||||
|
int mainY = centerY - lineHeight - 2;
|
||||||
int textWidth = client.font.width(line);
|
int textWidth = client.font.width(line);
|
||||||
graphics.drawString(client.font, line, (w - textWidth) / 2, h / 2, 0xFFFFFF, false);
|
graphics.drawString(client.font, line, (w - textWidth) / 2, mainY, 0xFFFFFF, false);
|
||||||
|
|
||||||
|
long nextMin = nextDeathWaitMinutes;
|
||||||
|
if (nextMin > 0L) {
|
||||||
|
Component sub = Component.translatable("respawn_backoff.hud.next_death", nextMin);
|
||||||
|
int subW = client.font.width(sub);
|
||||||
|
graphics.drawString(client.font, sub, (w - subW) / 2, centerY + 4, 0xA0A0A0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearForDisconnect() {
|
public static void clearForDisconnect() {
|
||||||
overlayActive = false;
|
overlayActive = false;
|
||||||
cooldownEndEpochMs = 0L;
|
cooldownEndEpochMs = 0L;
|
||||||
|
nextDeathWaitMinutes = 0L;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import net.minecraft.network.codec.StreamCodec;
|
|||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public record CooldownSyncPayload(boolean active, long cooldownEndEpochMs) implements CustomPacketPayload {
|
public record CooldownSyncPayload(boolean active, long cooldownEndEpochMs, long nextDeathWaitMinutes) implements CustomPacketPayload {
|
||||||
public static final CustomPacketPayload.Type<CooldownSyncPayload> TYPE = new CustomPacketPayload.Type<>(
|
public static final CustomPacketPayload.Type<CooldownSyncPayload> TYPE = new CustomPacketPayload.Type<>(
|
||||||
ResourceLocation.fromNamespaceAndPath(RespawnBackoffMod.MOD_ID, "cooldown_sync")
|
ResourceLocation.fromNamespaceAndPath(RespawnBackoffMod.MOD_ID, "cooldown_sync")
|
||||||
);
|
);
|
||||||
@@ -14,8 +14,9 @@ public record CooldownSyncPayload(boolean active, long cooldownEndEpochMs) imple
|
|||||||
(RegistryFriendlyByteBuf buf, CooldownSyncPayload payload) -> {
|
(RegistryFriendlyByteBuf buf, CooldownSyncPayload payload) -> {
|
||||||
buf.writeBoolean(payload.active());
|
buf.writeBoolean(payload.active());
|
||||||
buf.writeLong(payload.cooldownEndEpochMs());
|
buf.writeLong(payload.cooldownEndEpochMs());
|
||||||
|
buf.writeLong(payload.nextDeathWaitMinutes());
|
||||||
},
|
},
|
||||||
buf -> new CooldownSyncPayload(buf.readBoolean(), buf.readLong())
|
buf -> new CooldownSyncPayload(buf.readBoolean(), buf.readLong(), buf.readLong())
|
||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,4 +30,12 @@ public record RespawnBackoffData(
|
|||||||
public boolean isCooldownFinished(long nowMs) {
|
public boolean isCooldownFinished(long nowMs) {
|
||||||
return cooldownEndEpochMs > 0L && nowMs >= cooldownEndEpochMs;
|
return cooldownEndEpochMs > 0L && nowMs >= cooldownEndEpochMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spectator wait length in whole minutes if the player dies again now (same formula as the next death).
|
||||||
|
*/
|
||||||
|
public long nextDeathWaitMinutes() {
|
||||||
|
int cappedExp = Math.min(exponent, 6);
|
||||||
|
return Math.min(1L << cappedExp, 64L);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ public final class RespawnBackoffNetworking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void sendCooldown(ServerPlayer player, boolean active, long cooldownEndEpochMs) {
|
public static void sendCooldown(ServerPlayer player, boolean active, long cooldownEndEpochMs) {
|
||||||
ServerPlayNetworking.send(player, new CooldownSyncPayload(active, cooldownEndEpochMs));
|
long nextMinutes = 0L;
|
||||||
|
if (active) {
|
||||||
|
RespawnBackoffData data = player.getAttachedOrElse(RespawnBackoffMod.RESPAWN_BACKOFF, RespawnBackoffData.DEFAULT);
|
||||||
|
nextMinutes = data.nextDeathWaitMinutes();
|
||||||
|
}
|
||||||
|
ServerPlayNetworking.send(player, new CooldownSyncPayload(active, cooldownEndEpochMs, nextMinutes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"respawn_backoff.hud.countdown": "Respawn in %s",
|
"respawn_backoff.hud.countdown": "Respawn in %s",
|
||||||
|
"respawn_backoff.hud.next_death": "If you die again: %s min",
|
||||||
"respawn_backoff.command.reset.single": "Reset respawn backoff for %s to the minimum (next death: 1 minute).",
|
"respawn_backoff.command.reset.single": "Reset respawn backoff for %s to the minimum (next death: 1 minute).",
|
||||||
"respawn_backoff.command.reset.multiple": "Reset respawn backoff to the minimum for %s players.",
|
"respawn_backoff.command.reset.multiple": "Reset respawn backoff to the minimum for %s players.",
|
||||||
"respawn_backoff.command.skip.single": "Skipped respawn wait for %s.",
|
"respawn_backoff.command.skip.single": "Skipped respawn wait for %s.",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"respawn_backoff.hud.countdown": "Возрождение через %s",
|
"respawn_backoff.hud.countdown": "Возрождение через %s",
|
||||||
|
"respawn_backoff.hud.next_death": "Если умрёте снова: %s мин.",
|
||||||
"respawn_backoff.command.reset.single": "Откат респавна для %s сброшен к минимуму (после следующей смерти: 1 минута).",
|
"respawn_backoff.command.reset.single": "Откат респавна для %s сброшен к минимуму (после следующей смерти: 1 минута).",
|
||||||
"respawn_backoff.command.reset.multiple": "Откат респавна сброшен к минимуму для %s игроков.",
|
"respawn_backoff.command.reset.multiple": "Откат респавна сброшен к минимуму для %s игроков.",
|
||||||
"respawn_backoff.command.skip.single": "Ожидание респавна для %s пропущено.",
|
"respawn_backoff.command.skip.single": "Ожидание респавна для %s пропущено.",
|
||||||
|
|||||||
Reference in New Issue
Block a user