diff --git a/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java b/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java index 04efb6e5..72b2cfb2 100644 --- a/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java +++ b/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia; +import java.util.List; import java.util.UUID; import javax.annotation.Nullable; @@ -12,14 +13,23 @@ import com.minelittlepony.unicopia.network.MsgRequestCapabilities; import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IView; import com.minelittlepony.unicopia.player.PlayerSpeciesList; +import com.minelittlepony.util.gui.ButtonGridLayout; +import com.minelittlepony.util.gui.UButton; import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiOptions; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; import net.minecraft.world.IInteractionObject; import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraftforge.client.event.EntityViewRenderEvent; import net.minecraftforge.client.event.FOVUpdateEvent; +import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.client.event.RenderLivingEvent; @@ -32,6 +42,8 @@ import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import static com.minelittlepony.util.gui.ButtonGridLayout.*; + @EventBusSubscriber(Side.CLIENT) public class UnicopiaClient extends UClient { @@ -55,6 +67,7 @@ public class UnicopiaClient extends UClient { } } + return UConfig.getInstance().getPrefferedRace(); } @@ -106,6 +119,44 @@ public class UnicopiaClient extends UClient { return Minecraft.getMinecraft().gameSettings.thirdPersonView; } + @SideOnly(Side.CLIENT) + @SubscribeEvent + public static void onDisplayGui(GuiScreenEvent.InitGuiEvent.Post event) { + if (event.getGui() instanceof GuiOptions) { + addUniButton(event); + } + } + + static void addUniButton(GuiScreenEvent.InitGuiEvent.Post event) { + ButtonGridLayout layout = new ButtonGridLayout(event.getButtonList()); + + GuiButton uni = new UButton(layout.getNextButtonId(), 0, 0, 150, 20, I18n.format("gui.unicopia"), b -> { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.BLOCK_ANVIL_USE, 1)); + b.displayString = "<< WIP >>"; + + return false; + }); + + List possibleXCandidates = list(layout.getColumns()); + List possibleYCandidates = list(layout.getRows()); + + uni.y = last(possibleYCandidates, 1); + + if (layout.getRows() + .filter(y -> layout.getRow(y).size() == 1).count() < 2) { + uni.y += 25; + uni.x = first(possibleXCandidates, 0); + + layout.getRow(last(possibleYCandidates, 0)).forEach(button -> { + button.y = Math.max(button.y, uni.y + uni.height + 13); + }); + } else { + uni.x = first(possibleXCandidates, 2); + } + + layout.getElements().add(uni); + } + @SideOnly(Side.CLIENT) @SubscribeEvent public static void preEntityRender(RenderLivingEvent.Pre event) { diff --git a/src/main/java/com/minelittlepony/util/gui/ButtonGridLayout.java b/src/main/java/com/minelittlepony/util/gui/ButtonGridLayout.java new file mode 100644 index 00000000..7d325579 --- /dev/null +++ b/src/main/java/com/minelittlepony/util/gui/ButtonGridLayout.java @@ -0,0 +1,90 @@ +package com.minelittlepony.util.gui; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import net.minecraft.client.gui.GuiButton; + +public class ButtonGridLayout { + + private List elements; + + private Map> leftLookup = new HashMap<>(); + private Map> topLookup = new HashMap<>(); + + private Map> idLookup = new HashMap<>(); + + private int nextButtonId = -1; + + public ButtonGridLayout(List elements) { + elements.forEach(this::addElement); + this.elements = elements; + } + + public int getNextButtonId() { + return nextButtonId++; + } + + public GuiButton addElement(GuiButton button) { + if (elements != null) { + elements.add(button); + } + getColumn(button.x).add(button); + getRow(button.y).add(button); + getButton(button.id).add(button); + + while (button.id >= nextButtonId) { + getNextButtonId(); + } + + return button; + } + + public List getElements() { + return elements; + } + + public List getRow(int y) { + return topLookup.computeIfAbsent(y, ArrayList::new); + } + + public List getColumn(int x) { + return leftLookup.computeIfAbsent(x, ArrayList::new); + } + + public List getButton(int id) { + return idLookup.computeIfAbsent(id, ArrayList::new); + } + + public Stream getButtonIds() { + return idLookup.keySet().stream().sorted(); + } + + public Stream getColumns() { + return leftLookup.keySet().stream().sorted(); + } + + public Stream getRows() { + return topLookup.keySet().stream().sorted(); + } + + public Stream getIds() { + return idLookup.keySet().stream().sorted(); + } + + public static List list(Stream s) { + return s.collect(Collectors.toList()); + } + + public static T first(List c, int i) { + return c.get(i); + } + + public static T last(List c, int i) { + return first(c, (c.size() - 1) - i); + } +} diff --git a/src/main/java/com/minelittlepony/util/gui/UButton.java b/src/main/java/com/minelittlepony/util/gui/UButton.java new file mode 100644 index 00000000..9883c983 --- /dev/null +++ b/src/main/java/com/minelittlepony/util/gui/UButton.java @@ -0,0 +1,24 @@ +package com.minelittlepony.util.gui; + +import java.util.function.Function; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; + +public class UButton extends GuiButton { + + private final Function action; + + public UButton(int id, int x, int y, int w, int h, String label, Function action) { + super(id, x, y, w, h, label); + this.action = action; + } + + public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { + if (super.mousePressed(mc, mouseX, mouseY)) { + return action.apply(this); + } + + return false; + } +} diff --git a/src/main/resources/assets/unicopia/lang/en_US.lang b/src/main/resources/assets/unicopia/lang/en_US.lang index 8644cb4f..2a9932b1 100644 --- a/src/main/resources/assets/unicopia/lang/en_US.lang +++ b/src/main/resources/assets/unicopia/lang/en_US.lang @@ -101,6 +101,8 @@ toxicity.fair.name=Fairly Toxic toxicity.severe.name=Toxic toxicity.lethal.name=Lethal +gui.unicopia=Unicopia... + commands.race.success.self=Your race has been updated commands.race.success.otherself=%s changed race to %s commands.race.success.other=Changed %s's race to %s