Spaces:
Build error
Build error
File size: 8,659 Bytes
d46f4a3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
package net.minecraft.client.gui.components;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.audio.ListenerTransform;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.sounds.SoundEventListener;
import net.minecraft.client.sounds.SoundManager;
import net.minecraft.client.sounds.WeighedSoundEvents;
import net.minecraft.network.chat.Component;
import net.minecraft.util.ARGB;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public class SubtitleOverlay implements SoundEventListener {
private static final long DISPLAY_TIME = 3000L;
private final Minecraft minecraft;
private final List<SubtitleOverlay.Subtitle> subtitles = Lists.newArrayList();
private boolean isListening;
private final List<SubtitleOverlay.Subtitle> audibleSubtitles = new ArrayList<>();
public SubtitleOverlay(Minecraft p_94641_) {
this.minecraft = p_94641_;
}
public void render(GuiGraphics p_282562_) {
SoundManager soundmanager = this.minecraft.getSoundManager();
if (!this.isListening && this.minecraft.options.showSubtitles().get()) {
soundmanager.addListener(this);
this.isListening = true;
} else if (this.isListening && !this.minecraft.options.showSubtitles().get()) {
soundmanager.removeListener(this);
this.isListening = false;
}
if (this.isListening) {
ListenerTransform listenertransform = soundmanager.getListenerTransform();
Vec3 vec3 = listenertransform.position();
Vec3 vec31 = listenertransform.forward();
Vec3 vec32 = listenertransform.right();
this.audibleSubtitles.clear();
for (SubtitleOverlay.Subtitle subtitleoverlay$subtitle : this.subtitles) {
if (subtitleoverlay$subtitle.isAudibleFrom(vec3)) {
this.audibleSubtitles.add(subtitleoverlay$subtitle);
}
}
if (!this.audibleSubtitles.isEmpty()) {
int l1 = 0;
int i2 = 0;
double d0 = this.minecraft.options.notificationDisplayTime().get();
Iterator<SubtitleOverlay.Subtitle> iterator = this.audibleSubtitles.iterator();
while (iterator.hasNext()) {
SubtitleOverlay.Subtitle subtitleoverlay$subtitle1 = iterator.next();
subtitleoverlay$subtitle1.purgeOldInstances(3000.0 * d0);
if (!subtitleoverlay$subtitle1.isStillActive()) {
iterator.remove();
} else {
i2 = Math.max(i2, this.minecraft.font.width(subtitleoverlay$subtitle1.getText()));
}
}
i2 += this.minecraft.font.width("<")
+ this.minecraft.font.width(" ")
+ this.minecraft.font.width(">")
+ this.minecraft.font.width(" ");
for (SubtitleOverlay.Subtitle subtitleoverlay$subtitle2 : this.audibleSubtitles) {
int i = 255;
Component component = subtitleoverlay$subtitle2.getText();
SubtitleOverlay.SoundPlayedAt subtitleoverlay$soundplayedat = subtitleoverlay$subtitle2.getClosest(vec3);
if (subtitleoverlay$soundplayedat != null) {
Vec3 vec33 = subtitleoverlay$soundplayedat.location.subtract(vec3).normalize();
double d1 = vec32.dot(vec33);
double d2 = vec31.dot(vec33);
boolean flag = d2 > 0.5;
int j = i2 / 2;
int k = 9;
int l = k / 2;
float f = 1.0F;
int i1 = this.minecraft.font.width(component);
int j1 = Mth.floor(
Mth.clampedLerp(255.0F, 75.0F, (float)(Util.getMillis() - subtitleoverlay$soundplayedat.time) / (float)(3000.0 * d0))
);
p_282562_.pose().pushPose();
p_282562_.pose()
.translate(
(float)p_282562_.guiWidth() - (float)j * 1.0F - 2.0F, (float)(p_282562_.guiHeight() - 35) - (float)(l1 * (k + 1)) * 1.0F, 0.0F
);
p_282562_.pose().scale(1.0F, 1.0F, 1.0F);
p_282562_.fill(-j - 1, -l - 1, j + 1, l + 1, this.minecraft.options.getBackgroundColor(0.8F));
int k1 = ARGB.color(255, j1, j1, j1);
if (!flag) {
if (d1 > 0.0) {
p_282562_.drawString(this.minecraft.font, ">", j - this.minecraft.font.width(">"), -l, k1);
} else if (d1 < 0.0) {
p_282562_.drawString(this.minecraft.font, "<", -j, -l, k1);
}
}
p_282562_.drawString(this.minecraft.font, component, -i1 / 2, -l, k1);
p_282562_.pose().popPose();
l1++;
}
}
}
}
}
@Override
public void onPlaySound(SoundInstance p_94645_, WeighedSoundEvents p_94646_, float p_311530_) {
if (p_94646_.getSubtitle() != null) {
Component component = p_94646_.getSubtitle();
if (!this.subtitles.isEmpty()) {
for (SubtitleOverlay.Subtitle subtitleoverlay$subtitle : this.subtitles) {
if (subtitleoverlay$subtitle.getText().equals(component)) {
subtitleoverlay$subtitle.refresh(new Vec3(p_94645_.getX(), p_94645_.getY(), p_94645_.getZ()));
return;
}
}
}
this.subtitles.add(new SubtitleOverlay.Subtitle(component, p_311530_, new Vec3(p_94645_.getX(), p_94645_.getY(), p_94645_.getZ())));
}
}
@OnlyIn(Dist.CLIENT)
static record SoundPlayedAt(Vec3 location, long time) {
}
@OnlyIn(Dist.CLIENT)
static class Subtitle {
private final Component text;
private final float range;
private final List<SubtitleOverlay.SoundPlayedAt> playedAt = new ArrayList<>();
public Subtitle(Component p_169072_, float p_312799_, Vec3 p_169073_) {
this.text = p_169072_;
this.range = p_312799_;
this.playedAt.add(new SubtitleOverlay.SoundPlayedAt(p_169073_, Util.getMillis()));
}
public Component getText() {
return this.text;
}
@Nullable
public SubtitleOverlay.SoundPlayedAt getClosest(Vec3 p_344371_) {
if (this.playedAt.isEmpty()) {
return null;
} else {
return this.playedAt.size() == 1
? this.playedAt.getFirst()
: this.playedAt.stream().min(Comparator.comparingDouble(p_344048_ -> p_344048_.location().distanceTo(p_344371_))).orElse(null);
}
}
public void refresh(Vec3 p_94657_) {
this.playedAt.removeIf(p_342347_ -> p_94657_.equals(p_342347_.location()));
this.playedAt.add(new SubtitleOverlay.SoundPlayedAt(p_94657_, Util.getMillis()));
}
public boolean isAudibleFrom(Vec3 p_313169_) {
if (Float.isInfinite(this.range)) {
return true;
} else if (this.playedAt.isEmpty()) {
return false;
} else {
SubtitleOverlay.SoundPlayedAt subtitleoverlay$soundplayedat = this.getClosest(p_313169_);
return subtitleoverlay$soundplayedat == null ? false : p_313169_.closerThan(subtitleoverlay$soundplayedat.location, (double)this.range);
}
}
public void purgeOldInstances(double p_345350_) {
long i = Util.getMillis();
this.playedAt.removeIf(p_342900_ -> (double)(i - p_342900_.time()) > p_345350_);
}
public boolean isStillActive() {
return !this.playedAt.isEmpty();
}
}
} |