Files
ReplayModCinematic/src/main/java/com/replaymod/extras/playeroverview/PlayerOverviewGui.java
Jonas Herzig 42aef017c1 Fix skin in Player Overview and first person on 1.8.9 (fixes #749)
No clue why `getResourceLocationForPlayerUUID` was implemented the way it was,
that commit dates back to 2015 (332c36a), but if the skin isn't loaded yet, it
won't load it, so sometimes it just won't show properly in first person and in
the Player Overview.
This commit just calls `AbstractClientPlayer.getSkinTexture` instead.

Unclear which MC versions are affected. At some point before 1.16.4 something
else was introduced which loads the skin for us, hence why modern versions were
not affected.
2022-07-17 16:02:41 +02:00

196 lines
8.9 KiB
Java

package com.replaymod.extras.playeroverview;
import com.replaymod.replay.ReplayModReplay;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.container.GuiClickable;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.container.GuiScreen;
import de.johni0702.minecraft.gui.container.GuiVerticalList;
import de.johni0702.minecraft.gui.element.GuiCheckbox;
import de.johni0702.minecraft.gui.element.GuiImage;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.element.GuiTooltip;
import de.johni0702.minecraft.gui.element.IGuiCheckbox;
import de.johni0702.minecraft.gui.function.Closeable;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.utils.Colors;
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;
//#if MC>=10904
import net.minecraft.entity.effect.StatusEffects;
//#else
//$$ import net.minecraft.potion.Potion;
//#endif
//#if MC>=10800
import net.minecraft.client.render.entity.PlayerModelPart;
//#endif
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class PlayerOverviewGui extends GuiScreen implements Closeable {
protected static final int ENTRY_WIDTH = 200;
public final GuiPanel contentPanel = new GuiPanel(this).setBackgroundColor(Colors.DARK_TRANSPARENT);
public final GuiLabel spectateLabel = new GuiLabel(contentPanel)
.setI18nText("replaymod.gui.playeroverview.spectate");
public final GuiLabel visibleLabel = new GuiLabel(contentPanel)
.setI18nText("replaymod.gui.playeroverview.visible");
public final GuiVerticalList playersScrollable = new GuiVerticalList(contentPanel)
.setDrawSlider(true).setDrawShadow(true);
public final GuiCheckbox saveCheckbox = new GuiCheckbox(contentPanel)
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.remembersettings.description"))
.setI18nLabel("replaymod.gui.playeroverview.remembersettings");
public final GuiCheckbox checkAll = new GuiCheckbox(contentPanel){
@Override
public void onClick() {
playersScrollable.invokeAll(IGuiCheckbox.class, e -> e.setChecked(true));
}
}.setLabel("").setChecked(true).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.showall"));
public final GuiCheckbox uncheckAll = new GuiCheckbox(contentPanel){
@Override
public void onClick() {
playersScrollable.invokeAll(IGuiCheckbox.class, e -> e.setChecked(false));
}
}.setLabel("").setChecked(false).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.hideall"));
{
setBackground(Background.NONE);
setTitle(new GuiLabel().setI18nText("replaymod.input.playeroverview"));
setLayout(new CustomLayout<GuiScreen>() {
@Override
protected void layout(GuiScreen container, int width, int height) {
size(contentPanel, ENTRY_WIDTH + 30, height - 40);
pos(contentPanel, width / 2 - width(contentPanel) / 2, 20);
}
});
contentPanel.setLayout(new CustomLayout<GuiPanel>() {
@Override
protected void layout(GuiPanel container, int width, int height) {
pos(spectateLabel, 10, 10);
pos(visibleLabel, width - 10 - width(visibleLabel), 10);
pos(playersScrollable, 10, y(spectateLabel) + height(spectateLabel) + 5);
size(playersScrollable, width - 10 - 5, height - 15 - height(saveCheckbox) - y(playersScrollable));
pos(saveCheckbox, 10, height - 10 - height(saveCheckbox));
pos(uncheckAll, width - width(uncheckAll) - 8, height - height(uncheckAll) - 10);
pos(checkAll, x(uncheckAll) - 3 - width(checkAll), y(uncheckAll));
}
});
}
private final PlayerOverview extra;
public PlayerOverviewGui(final PlayerOverview extra, List<PlayerEntity> players) {
this.extra = extra;
Collections.sort(players, new PlayerComparator()); // Sort by name, spectators last
for (final PlayerEntity p : players) {
if (!(p instanceof AbstractClientPlayerEntity)) continue;
final Identifier texture = ((AbstractClientPlayerEntity) p).getSkinTexture();
final GuiClickable panel = new GuiClickable().setLayout(new HorizontalLayout().setSpacing(2)).addElements(
new HorizontalLayout.Data(0.5), new GuiImage() {
@Override
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
renderer.bindTexture(texture);
renderer.drawTexturedRect(0, 0, 8, 8, 16, 16, 8, 8, 64, 64);
//#if MC>=10809
if (p.isPartVisible(PlayerModelPart.HAT)) {
//#else
//#if MC>=10800
//$$ if (p.func_175148_a(EnumPlayerModelParts.HAT)) {
//#else
//$$ {
//#endif
//#endif
renderer.drawTexturedRect(0, 0, 40, 8, size.getWidth(), size.getHeight(), 8, 8, 64, 64);
}
}
}.setSize(16, 16),
new GuiLabel().setText(
//#if MC>=11400
p.getName().getString()
//#else
//#if MC>=10800
//$$ p.getName()
//#else
//$$ p.getDisplayName()
//#endif
//#endif
).setColor(isSpectator(p) ? Colors.DKGREY : Colors.WHITE)
).onClick(new Runnable() {
@Override
public void run() {
ReplayModReplay.instance.getReplayHandler().spectateEntity(p);
}
});
final GuiCheckbox checkbox = new GuiCheckbox() {
@Override
public GuiCheckbox setChecked(boolean checked) {
extra.setHidden(p.getUuid(), !checked);
return super.setChecked(checked);
}
}.setChecked(!extra.isHidden(p.getUuid()));
new GuiPanel(playersScrollable.getListPanel()).setLayout(new CustomLayout<GuiPanel>() {
@Override
protected void layout(GuiPanel container, int width, int height) {
pos(panel, 5, 0);
pos(checkbox, width - width(checkbox) - 5, height / 2 - height(checkbox) / 2);
}
@Override
public ReadableDimension calcMinSize(GuiContainer<?> container) {
return new Dimension(ENTRY_WIDTH, panel.getMinSize().getHeight());
}
}).addElements(null, panel, checkbox);
}
saveCheckbox.setChecked(extra.isSavingEnabled()).onClick(new Runnable() {
@Override
public void run() {
extra.setSavingEnabled(saveCheckbox.isChecked());
}
});
ReplayModReplay.instance.getReplayHandler().getOverlay().setVisible(false);
}
@Override
public void close() {
ReplayModReplay.instance.getReplayHandler().getOverlay().setVisible(true);
extra.saveHiddenPlayers();
}
private static boolean isSpectator(PlayerEntity e) {
//#if MC>=10904
return e.isInvisible() && e.getStatusEffect(StatusEffects.INVISIBILITY) == null;
//#else
//$$ return e.isInvisible() && e.getActivePotionEffect(Potion.invisibility) == null;
//#endif
}
private static final class PlayerComparator implements Comparator<PlayerEntity> {
@Override
public int compare(PlayerEntity o1, PlayerEntity o2) {
if (isSpectator(o1) && !isSpectator(o2)) return 1;
if (isSpectator(o2) && !isSpectator(o1)) return -1;
//#if MC>=11400
return o1.getName().getString().compareToIgnoreCase(o2.getName().getString());
//#else
//#if MC>=10800
//$$ return o1.getName().compareToIgnoreCase(o2.getName());
//#else
//$$ return o1.getDisplayName().compareToIgnoreCase(o2.getDisplayName());
//#endif
//#endif
}
}
}