minecraft-src/net/minecraft/client/gui/components/BossHealthOverlay.java
2025-07-04 02:00:41 +03:00

187 lines
6.9 KiB
Java

package net.minecraft.client.gui.components;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.UUID;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundBossEventPacket;
import net.minecraft.network.protocol.game.ClientboundBossEventPacket.Handler;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.util.profiling.Profiler;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.BossEvent;
import net.minecraft.world.BossEvent.BossBarColor;
import net.minecraft.world.BossEvent.BossBarOverlay;
@Environment(EnvType.CLIENT)
public class BossHealthOverlay {
private static final int BAR_WIDTH = 182;
private static final int BAR_HEIGHT = 5;
private static final ResourceLocation[] BAR_BACKGROUND_SPRITES = new ResourceLocation[]{
ResourceLocation.withDefaultNamespace("boss_bar/pink_background"),
ResourceLocation.withDefaultNamespace("boss_bar/blue_background"),
ResourceLocation.withDefaultNamespace("boss_bar/red_background"),
ResourceLocation.withDefaultNamespace("boss_bar/green_background"),
ResourceLocation.withDefaultNamespace("boss_bar/yellow_background"),
ResourceLocation.withDefaultNamespace("boss_bar/purple_background"),
ResourceLocation.withDefaultNamespace("boss_bar/white_background")
};
private static final ResourceLocation[] BAR_PROGRESS_SPRITES = new ResourceLocation[]{
ResourceLocation.withDefaultNamespace("boss_bar/pink_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/blue_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/red_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/green_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/yellow_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/purple_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/white_progress")
};
private static final ResourceLocation[] OVERLAY_BACKGROUND_SPRITES = new ResourceLocation[]{
ResourceLocation.withDefaultNamespace("boss_bar/notched_6_background"),
ResourceLocation.withDefaultNamespace("boss_bar/notched_10_background"),
ResourceLocation.withDefaultNamespace("boss_bar/notched_12_background"),
ResourceLocation.withDefaultNamespace("boss_bar/notched_20_background")
};
private static final ResourceLocation[] OVERLAY_PROGRESS_SPRITES = new ResourceLocation[]{
ResourceLocation.withDefaultNamespace("boss_bar/notched_6_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/notched_10_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/notched_12_progress"),
ResourceLocation.withDefaultNamespace("boss_bar/notched_20_progress")
};
private final Minecraft minecraft;
final Map<UUID, LerpingBossEvent> events = Maps.<UUID, LerpingBossEvent>newLinkedHashMap();
public BossHealthOverlay(Minecraft minecraft) {
this.minecraft = minecraft;
}
public void render(GuiGraphics guiGraphics) {
if (!this.events.isEmpty()) {
ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push("bossHealth");
int i = guiGraphics.guiWidth();
int j = 12;
for (LerpingBossEvent lerpingBossEvent : this.events.values()) {
int k = i / 2 - 91;
this.drawBar(guiGraphics, k, j, lerpingBossEvent);
Component component = lerpingBossEvent.getName();
int m = this.minecraft.font.width(component);
int n = i / 2 - m / 2;
int o = j - 9;
guiGraphics.drawString(this.minecraft.font, component, n, o, 16777215);
j += 10 + 9;
if (j >= guiGraphics.guiHeight() / 3) {
break;
}
}
profilerFiller.pop();
}
}
private void drawBar(GuiGraphics guiGraphics, int x, int y, BossEvent bossEvent) {
this.drawBar(guiGraphics, x, y, bossEvent, 182, BAR_BACKGROUND_SPRITES, OVERLAY_BACKGROUND_SPRITES);
int i = Mth.lerpDiscrete(bossEvent.getProgress(), 0, 182);
if (i > 0) {
this.drawBar(guiGraphics, x, y, bossEvent, i, BAR_PROGRESS_SPRITES, OVERLAY_PROGRESS_SPRITES);
}
}
private void drawBar(
GuiGraphics guiGraphics, int x, int y, BossEvent bossEvent, int progress, ResourceLocation[] barProgressSprites, ResourceLocation[] overlayProgressSprites
) {
guiGraphics.blitSprite(RenderType::guiTextured, barProgressSprites[bossEvent.getColor().ordinal()], 182, 5, 0, 0, x, y, progress, 5);
if (bossEvent.getOverlay() != BossBarOverlay.PROGRESS) {
guiGraphics.blitSprite(RenderType::guiTextured, overlayProgressSprites[bossEvent.getOverlay().ordinal() - 1], 182, 5, 0, 0, x, y, progress, 5);
}
}
public void update(ClientboundBossEventPacket packet) {
packet.dispatch(
new Handler() {
@Override
public void add(
UUID id, Component name, float progress, BossBarColor color, BossBarOverlay overlay, boolean darkenScreen, boolean playMusic, boolean createWorldFog
) {
BossHealthOverlay.this.events.put(id, new LerpingBossEvent(id, name, progress, color, overlay, darkenScreen, playMusic, createWorldFog));
}
@Override
public void remove(UUID id) {
BossHealthOverlay.this.events.remove(id);
}
@Override
public void updateProgress(UUID id, float progress) {
((LerpingBossEvent)BossHealthOverlay.this.events.get(id)).setProgress(progress);
}
@Override
public void updateName(UUID id, Component name) {
((LerpingBossEvent)BossHealthOverlay.this.events.get(id)).setName(name);
}
@Override
public void updateStyle(UUID id, BossBarColor color, BossBarOverlay overlay) {
LerpingBossEvent lerpingBossEvent = (LerpingBossEvent)BossHealthOverlay.this.events.get(id);
lerpingBossEvent.setColor(color);
lerpingBossEvent.setOverlay(overlay);
}
@Override
public void updateProperties(UUID id, boolean darkenScreen, boolean playMusic, boolean createWorldFog) {
LerpingBossEvent lerpingBossEvent = (LerpingBossEvent)BossHealthOverlay.this.events.get(id);
lerpingBossEvent.setDarkenScreen(darkenScreen);
lerpingBossEvent.setPlayBossMusic(playMusic);
lerpingBossEvent.setCreateWorldFog(createWorldFog);
}
}
);
}
public void reset() {
this.events.clear();
}
public boolean shouldPlayMusic() {
if (!this.events.isEmpty()) {
for (BossEvent bossEvent : this.events.values()) {
if (bossEvent.shouldPlayBossMusic()) {
return true;
}
}
}
return false;
}
public boolean shouldDarkenScreen() {
if (!this.events.isEmpty()) {
for (BossEvent bossEvent : this.events.values()) {
if (bossEvent.shouldDarkenScreen()) {
return true;
}
}
}
return false;
}
public boolean shouldCreateWorldFog() {
if (!this.events.isEmpty()) {
for (BossEvent bossEvent : this.events.values()) {
if (bossEvent.shouldCreateWorldFog()) {
return true;
}
}
}
return false;
}
}