Code/net/minecraft/client/gui/screens/worldselection/EditGameRulesScreen.java

359 lines
15 KiB
Java

package net.minecraft.client.gui.screens.worldselection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableList.Builder;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.client.gui.components.CycleButton;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
import net.minecraft.client.gui.layouts.LinearLayout;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.narration.NarratedElementType;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FormattedCharSequence;
import net.minecraft.world.level.GameRules;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public class EditGameRulesScreen extends Screen {
private static final Component TITLE = Component.translatable("editGamerule.title");
private static final int SPACING = 8;
final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this);
private final Consumer<Optional<GameRules>> exitCallback;
private final Set<EditGameRulesScreen.RuleEntry> invalidEntries = Sets.newHashSet();
private final GameRules gameRules;
@Nullable
private EditGameRulesScreen.RuleList ruleList;
@Nullable
private Button doneButton;
public EditGameRulesScreen(GameRules p_101051_, Consumer<Optional<GameRules>> p_101052_) {
super(TITLE);
this.gameRules = p_101051_;
this.exitCallback = p_101052_;
}
@Override
protected void init() {
this.layout.addTitleHeader(TITLE, this.font);
this.ruleList = this.layout.addToContents(new EditGameRulesScreen.RuleList(this.gameRules));
LinearLayout linearlayout = this.layout.addToFooter(LinearLayout.horizontal().spacing(8));
this.doneButton = linearlayout.addChild(
Button.builder(CommonComponents.GUI_DONE, p_101059_ -> this.exitCallback.accept(Optional.of(this.gameRules))).build()
);
linearlayout.addChild(Button.builder(CommonComponents.GUI_CANCEL, p_325430_ -> this.onClose()).build());
this.layout.visitWidgets(p_325432_ -> {
AbstractWidget abstractwidget = this.addRenderableWidget(p_325432_);
});
this.repositionElements();
}
@Override
protected void repositionElements() {
this.layout.arrangeElements();
if (this.ruleList != null) {
this.ruleList.updateSize(this.width, this.layout);
}
}
@Override
public void onClose() {
this.exitCallback.accept(Optional.empty());
}
private void updateDoneButton() {
if (this.doneButton != null) {
this.doneButton.active = this.invalidEntries.isEmpty();
}
}
void markInvalid(EditGameRulesScreen.RuleEntry p_101061_) {
this.invalidEntries.add(p_101061_);
this.updateDoneButton();
}
void clearInvalid(EditGameRulesScreen.RuleEntry p_101075_) {
this.invalidEntries.remove(p_101075_);
this.updateDoneButton();
}
@OnlyIn(Dist.CLIENT)
public class BooleanRuleEntry extends EditGameRulesScreen.GameRuleEntry {
private final CycleButton<Boolean> checkbox;
public BooleanRuleEntry(
final Component p_101101_, final List<FormattedCharSequence> p_101102_, final String p_101103_, final GameRules.BooleanValue p_101104_
) {
super(p_101102_, p_101101_);
this.checkbox = CycleButton.onOffBuilder(p_101104_.get())
.displayOnlyValue()
.withCustomNarration(p_170219_ -> p_170219_.createDefaultNarrationMessage().append("\n").append(p_101103_))
.create(10, 5, 44, 20, p_101101_, (p_170215_, p_170216_) -> p_101104_.set(p_170216_, null));
this.children.add(this.checkbox);
}
@Override
public void render(
GuiGraphics p_281587_,
int p_281471_,
int p_281257_,
int p_282541_,
int p_282993_,
int p_283543_,
int p_281322_,
int p_282930_,
boolean p_283227_,
float p_283364_
) {
this.renderLabel(p_281587_, p_281257_, p_282541_);
this.checkbox.setX(p_282541_ + p_282993_ - 45);
this.checkbox.setY(p_281257_);
this.checkbox.render(p_281587_, p_281322_, p_282930_, p_283364_);
}
}
@OnlyIn(Dist.CLIENT)
public class CategoryRuleEntry extends EditGameRulesScreen.RuleEntry {
final Component label;
public CategoryRuleEntry(final Component p_101141_) {
super(null);
this.label = p_101141_;
}
@Override
public void render(
GuiGraphics p_283335_,
int p_283214_,
int p_283476_,
int p_281365_,
int p_281817_,
int p_283006_,
int p_282893_,
int p_282500_,
boolean p_283421_,
float p_282445_
) {
p_283335_.drawCenteredString(EditGameRulesScreen.this.minecraft.font, this.label, p_281365_ + p_281817_ / 2, p_283476_ + 5, -1);
}
@Override
public List<? extends GuiEventListener> children() {
return ImmutableList.of();
}
@Override
public List<? extends NarratableEntry> narratables() {
return ImmutableList.of(new NarratableEntry() {
@Override
public NarratableEntry.NarrationPriority narrationPriority() {
return NarratableEntry.NarrationPriority.HOVERED;
}
@Override
public void updateNarration(NarrationElementOutput p_170225_) {
p_170225_.add(NarratedElementType.TITLE, CategoryRuleEntry.this.label);
}
});
}
}
@FunctionalInterface
@OnlyIn(Dist.CLIENT)
interface EntryFactory<T extends GameRules.Value<T>> {
EditGameRulesScreen.RuleEntry create(Component p_101155_, List<FormattedCharSequence> p_101156_, String p_101157_, T p_101158_);
}
@OnlyIn(Dist.CLIENT)
public abstract class GameRuleEntry extends EditGameRulesScreen.RuleEntry {
private final List<FormattedCharSequence> label;
protected final List<AbstractWidget> children = Lists.newArrayList();
public GameRuleEntry(@Nullable final List<FormattedCharSequence> p_101164_, final Component p_101165_) {
super(p_101164_);
this.label = EditGameRulesScreen.this.minecraft.font.split(p_101165_, 175);
}
@Override
public List<? extends GuiEventListener> children() {
return this.children;
}
@Override
public List<? extends NarratableEntry> narratables() {
return this.children;
}
protected void renderLabel(GuiGraphics p_282711_, int p_281539_, int p_281414_) {
if (this.label.size() == 1) {
p_282711_.drawString(EditGameRulesScreen.this.minecraft.font, this.label.get(0), p_281414_, p_281539_ + 5, -1);
} else if (this.label.size() >= 2) {
p_282711_.drawString(EditGameRulesScreen.this.minecraft.font, this.label.get(0), p_281414_, p_281539_, -1);
p_282711_.drawString(EditGameRulesScreen.this.minecraft.font, this.label.get(1), p_281414_, p_281539_ + 10, -1);
}
}
}
@OnlyIn(Dist.CLIENT)
public class IntegerRuleEntry extends EditGameRulesScreen.GameRuleEntry {
private final EditBox input;
public IntegerRuleEntry(
final Component p_101175_, final List<FormattedCharSequence> p_101176_, final String p_101177_, final GameRules.IntegerValue p_101178_
) {
super(p_101176_, p_101175_);
this.input = new EditBox(
EditGameRulesScreen.this.minecraft.font, 10, 5, 44, 20, p_101175_.copy().append("\n").append(p_101177_).append("\n")
);
this.input.setValue(Integer.toString(p_101178_.get()));
this.input.setResponder(p_101181_ -> {
if (p_101178_.tryDeserialize(p_101181_)) {
this.input.setTextColor(14737632);
EditGameRulesScreen.this.clearInvalid(this);
} else {
this.input.setTextColor(-65536);
EditGameRulesScreen.this.markInvalid(this);
}
});
this.children.add(this.input);
}
@Override
public void render(
GuiGraphics p_281756_,
int p_281882_,
int p_281876_,
int p_283136_,
int p_283044_,
int p_282526_,
int p_282433_,
int p_281816_,
boolean p_282227_,
float p_281751_
) {
this.renderLabel(p_281756_, p_281876_, p_283136_);
this.input.setX(p_283136_ + p_283044_ - 45);
this.input.setY(p_281876_);
this.input.render(p_281756_, p_282433_, p_281816_, p_281751_);
}
}
@OnlyIn(Dist.CLIENT)
public abstract static class RuleEntry extends ContainerObjectSelectionList.Entry<EditGameRulesScreen.RuleEntry> {
@Nullable
final List<FormattedCharSequence> tooltip;
public RuleEntry(@Nullable List<FormattedCharSequence> p_194062_) {
this.tooltip = p_194062_;
}
}
@OnlyIn(Dist.CLIENT)
public class RuleList extends ContainerObjectSelectionList<EditGameRulesScreen.RuleEntry> {
private static final int ITEM_HEIGHT = 24;
public RuleList(final GameRules p_101203_) {
super(
Minecraft.getInstance(),
EditGameRulesScreen.this.width,
EditGameRulesScreen.this.layout.getContentHeight(),
EditGameRulesScreen.this.layout.getHeaderHeight(),
24
);
final Map<GameRules.Category, Map<GameRules.Key<?>, EditGameRulesScreen.RuleEntry>> map = Maps.newHashMap();
p_101203_.visitGameRuleTypes(
new GameRules.GameRuleTypeVisitor() {
@Override
public void visitBoolean(GameRules.Key<GameRules.BooleanValue> p_101238_, GameRules.Type<GameRules.BooleanValue> p_101239_) {
this.addEntry(
p_101238_,
(p_101228_, p_101229_, p_101230_, p_101231_) -> EditGameRulesScreen.this.new BooleanRuleEntry(
p_101228_, p_101229_, p_101230_, p_101231_
)
);
}
@Override
public void visitInteger(GameRules.Key<GameRules.IntegerValue> p_101241_, GameRules.Type<GameRules.IntegerValue> p_101242_) {
this.addEntry(
p_101241_,
(p_101233_, p_101234_, p_101235_, p_101236_) -> EditGameRulesScreen.this.new IntegerRuleEntry(
p_101233_, p_101234_, p_101235_, p_101236_
)
);
}
private <T extends GameRules.Value<T>> void addEntry(GameRules.Key<T> p_101225_, EditGameRulesScreen.EntryFactory<T> p_101226_) {
Component component = Component.translatable(p_101225_.getDescriptionId());
Component component1 = Component.literal(p_101225_.getId()).withStyle(ChatFormatting.YELLOW);
T t = p_101203_.getRule(p_101225_);
String s = t.serialize();
Component component2 = Component.translatable("editGamerule.default", Component.literal(s)).withStyle(ChatFormatting.GRAY);
String s1 = p_101225_.getDescriptionId() + ".description";
List<FormattedCharSequence> list;
String s2;
if (I18n.exists(s1)) {
Builder<FormattedCharSequence> builder = ImmutableList.<FormattedCharSequence>builder().add(component1.getVisualOrderText());
Component component3 = Component.translatable(s1);
EditGameRulesScreen.this.font.split(component3, 150).forEach(builder::add);
list = builder.add(component2.getVisualOrderText()).build();
s2 = component3.getString() + "\n" + component2.getString();
} else {
list = ImmutableList.of(component1.getVisualOrderText(), component2.getVisualOrderText());
s2 = component2.getString();
}
map.computeIfAbsent(p_101225_.getCategory(), p_101223_ -> Maps.newHashMap()).put(p_101225_, p_101226_.create(component, list, s2, t));
}
}
);
map.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEach(
p_101210_ -> {
this.addEntry(
EditGameRulesScreen.this.new CategoryRuleEntry(
Component.translatable(p_101210_.getKey().getDescriptionId()).withStyle(ChatFormatting.BOLD, ChatFormatting.YELLOW)
)
);
p_101210_.getValue()
.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey(Comparator.comparing(GameRules.Key::getId)))
.forEach(p_170229_ -> this.addEntry(p_170229_.getValue()));
}
);
}
@Override
public void renderWidget(GuiGraphics p_309387_, int p_311816_, int p_311348_, float p_311962_) {
super.renderWidget(p_309387_, p_311816_, p_311348_, p_311962_);
EditGameRulesScreen.RuleEntry editgamerulesscreen$ruleentry = this.getHovered();
if (editgamerulesscreen$ruleentry != null && editgamerulesscreen$ruleentry.tooltip != null) {
EditGameRulesScreen.this.setTooltipForNextRenderPass(editgamerulesscreen$ruleentry.tooltip);
}
}
}
}