187 lines
6.9 KiB
Java
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;
|
|
}
|
|
}
|