/*
* Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
* Copyright (C) 2021 cyoung06
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package kr.syeyoung.dungeonsguide.features.impl.secret.mechanicbrowser;
import kr.syeyoung.dungeonsguide.DungeonsGuide;
import kr.syeyoung.dungeonsguide.dungeon.DungeonContext;
import kr.syeyoung.dungeonsguide.dungeon.actions.tree.ActionRoute;
import kr.syeyoung.dungeonsguide.dungeon.mechanics.*;
import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom;
import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
import kr.syeyoung.dungeonsguide.gui.MPanel;
import kr.syeyoung.dungeonsguide.gui.elements.MList;
import kr.syeyoung.dungeonsguide.gui.elements.MPanelScaledGUI;
import kr.syeyoung.dungeonsguide.gui.elements.MScrollablePanel;
import kr.syeyoung.dungeonsguide.roomprocessor.GeneralRoomProcessor;
import lombok.Getter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.MathHelper;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import java.awt.*;
import java.util.*;
import java.util.List;
public class PanelMechanicBrowser extends MPanelScaledGUI {
private FeatureMechanicBrowse feature;
private MScrollablePanel scrollablePanel;
private MList mList;
private MechanicBrowserTooltip mechanicBrowserTooltip;
public PanelMechanicBrowser(FeatureMechanicBrowse mechanicBrowse) {
this.feature = mechanicBrowse;
this.scrollablePanel = new MScrollablePanel(1);
add(this.scrollablePanel);
scrollablePanel.getScrollBarY().setWidth(0);
mList = new MList() {
@Override
public void resize(int parentWidth, int parentHeight) {
setBounds(new Rectangle(0,0,parentWidth,parentHeight));
Dimension prefSize = getPreferredSize();
int hei = prefSize.height;
setBounds(new Rectangle(0,0,parentWidth,hei));
realignChildren();
}
};
mList.setDrawLine(false); mList.setGap(0);
scrollablePanel.add(mList);
}
@Override
public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
toggleTooltip(openGUI());
Optional dungeonRoomOpt = Optional.ofNullable(DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext())
.map(DungeonContext::getMapProcessor).map(a->a.worldPointToRoomPoint(Minecraft.getMinecraft().thePlayer.getPosition()))
.map(a -> DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext().getRoomMapper().get(a));
DungeonRoom dungeonRoom = dungeonRoomOpt.orElse(null);
renderTick(dungeonRoom);
if (dungeonRoom == null) return;
if (!(dungeonRoom.getRoomProcessor() instanceof GeneralRoomProcessor)) return;
GeneralRoomProcessor grp = (GeneralRoomProcessor) dungeonRoom.getRoomProcessor();
FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
Dimension effectiveDim = getEffectiveDimension();
Gui.drawRect(0, 0, effectiveDim.width, fr.FONT_HEIGHT + 4, 0xFF444444);
Gui.drawRect(1, 1, effectiveDim.width - 1, fr.FONT_HEIGHT + 3, 0xFF262626);
GlStateManager.enableBlend();
GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
fr.drawString("Selected: ", 2,2, 0xFFAAAAAA);
if (grp.getPath("MECH-BROWSER") == null)
fr.drawString("Nothing", fr.getStringWidth("Selected: ") + 2,2, 0xFFAA0000);
else {
ActionRoute route = grp.getPath("MECH-BROWSER");
fr.drawString(route.getMechanic()+" -> "+route.getState(), fr.getStringWidth("Selected: ") + 2,2, 0xFFFFFF00);
}
fr.drawString("Open Chat to Select Secrets", 2, fr.FONT_HEIGHT + 5, 0xFFAAAAAA);
if (!openGUI()) return;
Gui.drawRect(0, fr.FONT_HEIGHT + 4, effectiveDim.width, effectiveDim.height, 0xFF444444);
Gui.drawRect(1, fr.FONT_HEIGHT + 5, effectiveDim.width - 1,effectiveDim.height - 1, 0xFF262626);
}
private UUID lastRoomUID = null;
public void renderTick(DungeonRoom dungeonRoom) {
if (dungeonRoom == null && lastRoomUID != null) {
lastRoomUID = null;
for (MPanel childComponent : mList.getChildComponents()) {
mList.remove(childComponent);
}
if (mechanicBrowserTooltip != null) {
mechanicBrowserTooltip.close();
mechanicBrowserTooltip = null;
}
selectedID = null;
} else if (dungeonRoom != null && lastRoomUID != dungeonRoom.getDungeonRoomInfo().getUuid()) {
lastRoomUID = dungeonRoom.getDungeonRoomInfo().getUuid();
// SETUP THINGS.
for (MPanel childComponent : mList.getChildComponents()) {
mList.remove(childComponent);
}
if (mechanicBrowserTooltip != null) {
mechanicBrowserTooltip.close();
mechanicBrowserTooltip = null;
}
selectedID = null;
mList.add(new MechanicBrowserElement(() -> "§bCancel Current", false, (pt, me) -> cancel(pt)));
boolean found = false;
for (Map.Entry value : dungeonRoom.getMechanics().entrySet()) {
if (value.getValue() instanceof DungeonFairySoul) {
if (!found) {
mList.add(new MechanicBrowserElement(() -> "Fairy Soul", true, null));
found = true;
}
mList.add(new MechanicBrowserElement(() -> value.getKey()+" §7("+ value.getValue().getCurrentState(dungeonRoom) +", "+
(value.getValue().getRepresentingPoint(dungeonRoom) != null ?
String.format("%.1f", MathHelper.sqrt_double(value.getValue().getRepresentingPoint(dungeonRoom).getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))) : "")
+"m)", false, (me, pt) -> onElementClick(value.getKey(), value.getValue(), pt, me)));
}
}
found = false;
for (Map.Entry value : dungeonRoom.getMechanics().entrySet()) {
if (value.getValue() instanceof DungeonSecret) {
if (!found) {
mList.add(new MechanicBrowserElement(() -> "Secrets", true, null));
found = true;
}
mList.add(new MechanicBrowserElement(() -> value.getKey()+" §7("+ value.getValue().getCurrentState(dungeonRoom) +", "+
(value.getValue().getRepresentingPoint(dungeonRoom) != null ?
String.format("%.1f", MathHelper.sqrt_double(value.getValue().getRepresentingPoint(dungeonRoom).getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))) : "")
+"m)", false, (me, pt) -> onElementClick(value.getKey(), value.getValue(), pt, me)));
}
}
found = false;
for (Map.Entry value : dungeonRoom.getMechanics().entrySet()) {
if (value.getValue() instanceof DungeonTomb) {
if (!found) {
mList.add(new MechanicBrowserElement(() -> "Crypts", true, null));
found = true;
}
mList.add(new MechanicBrowserElement(() -> value.getKey()+" §7("+ value.getValue().getCurrentState(dungeonRoom) +", "+
(value.getValue().getRepresentingPoint(dungeonRoom) != null ?
String.format("%.1f", MathHelper.sqrt_double(value.getValue().getRepresentingPoint(dungeonRoom).getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))) : "")
+"m)", false, (me, pt) -> onElementClick(value.getKey(), value.getValue(), pt, me)));
}
}
found = false;
for (Map.Entry value : dungeonRoom.getMechanics().entrySet()) {
if (value.getValue() instanceof DungeonNPC) {
if (!found) {
mList.add(new MechanicBrowserElement(() -> "NPC", true, null));
found = true;
}
mList.add(new MechanicBrowserElement(() -> value.getKey()+" §7("+ value.getValue().getCurrentState(dungeonRoom) +", "+
(value.getValue().getRepresentingPoint(dungeonRoom) != null ?
String.format("%.1f", MathHelper.sqrt_double(value.getValue().getRepresentingPoint(dungeonRoom).getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))) : "")
+"m)", false, (me, pt) -> onElementClick(value.getKey(), value.getValue(), pt, me)));
}
}
found = false;
for (Map.Entry value : dungeonRoom.getMechanics().entrySet()) {
if (value.getValue() instanceof DungeonJournal) {
if (!found) {
mList.add(new MechanicBrowserElement(() -> "Journals", true, null));
found = true;
}
mList.add(new MechanicBrowserElement(() -> value.getKey()+" §7("+ value.getValue().getCurrentState(dungeonRoom) +", "+
(value.getValue().getRepresentingPoint(dungeonRoom) != null ?
String.format("%.1f", MathHelper.sqrt_double(value.getValue().getRepresentingPoint(dungeonRoom).getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))) : "")
+"m)", false, (me, pt) -> onElementClick(value.getKey(), value.getValue(), pt, me)));
}
}
found = false;
for (Map.Entry value : dungeonRoom.getMechanics().entrySet()) {
if (value.getValue() instanceof DungeonRoomDoor){
if (!found) {
mList.add(new MechanicBrowserElement(() -> "Gates", true, null));
found = true;
}
mList.add(new MechanicBrowserElement(() -> value.getKey()+" §7("+ value.getValue().getCurrentState(dungeonRoom) +", "+
(value.getValue().getRepresentingPoint(dungeonRoom) != null ?
String.format("%.1f", MathHelper.sqrt_double(value.getValue().getRepresentingPoint(dungeonRoom).getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))) : "")
+"m)", false, (me, pt) -> onElementClick(value.getKey(), value.getValue(), pt, me)));
}
}
found = false;
for (Map.Entry value : dungeonRoom.getMechanics().entrySet()) {
if (value.getValue() instanceof DungeonDoor || value.getValue() instanceof DungeonBreakableWall || value.getValue() instanceof DungeonLever
|| value.getValue() instanceof DungeonOnewayDoor || value.getValue() instanceof DungeonOnewayLever || value.getValue() instanceof DungeonPressurePlate) {
if (!found) {
mList.add(new MechanicBrowserElement(() -> "ETC", true, null));
found = true;
}
mList.add(new MechanicBrowserElement(() -> value.getKey()+" §7("+ value.getValue().getCurrentState(dungeonRoom) +", "+
(value.getValue().getRepresentingPoint(dungeonRoom) != null ?
String.format("%.1f", MathHelper.sqrt_double(value.getValue().getRepresentingPoint(dungeonRoom).getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))) : "")
+"m)", false, (me, pt) -> onElementClick(value.getKey(), value.getValue(), pt, me)));
}
}
scrollablePanel.evalulateContentArea();
}
}
private int latestTooltipDY;
@Getter
private String selectedID = null;
public void onElementClick(String id, DungeonMechanic dungeonMechanic, Point pt, MechanicBrowserElement mechanicBrowserElement) {
Optional dungeonRoomOpt = Optional.ofNullable(DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext())
.map(DungeonContext::getMapProcessor).map(a->a.worldPointToRoomPoint(Minecraft.getMinecraft().thePlayer.getPosition()))
.map(a -> DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext().getRoomMapper().get(a));
selectedID = id;
DungeonRoom dungeonRoom = dungeonRoomOpt.orElse(null);
if (dungeonRoom == null) return;
DungeonMechanic dungeonMechanic1 = dungeonRoom.getMechanics().get(id);
if (dungeonMechanic1 != dungeonMechanic) return;
Set states = dungeonMechanic1.getPossibleStates(dungeonRoom);
if (mechanicBrowserTooltip != null) {
mechanicBrowserTooltip.close();
}
latestTooltipDY = (int) (pt.y * getScale() - bounds.y - 1);
mechanicBrowserTooltip = new MechanicBrowserTooltip();
for (String state : states) {
mechanicBrowserTooltip.getMList().add(new MechanicBrowserElement(() -> state, false, (m2, pt2) -> {
if (dungeonRoom.getRoomProcessor() instanceof GeneralRoomProcessor)
((GeneralRoomProcessor)dungeonRoom.getRoomProcessor()).pathfind("MECH-BROWSER", id, state, FeatureRegistry.SECRET_LINE_PROPERTIES_SECRET_BROWSER.getRouteProperties());
// mechanicBrowserTooltip.close();
// mechanicBrowserTooltip = null;
}));
}
mechanicBrowserTooltip.setScale(getScale());
Dimension prefSize = mechanicBrowserTooltip.getPreferredSize();
mechanicBrowserTooltip.setBounds(new Rectangle(bounds.x +
(bounds.x > Minecraft.getMinecraft().displayWidth/2 ? -prefSize.width : bounds.width), latestTooltipDY + bounds.y, prefSize.width, prefSize.height));
mechanicBrowserTooltip.open(this);
}
public void cancel(MechanicBrowserElement mechanicBrowserElement) {
Optional dungeonRoomOpt = Optional.ofNullable(DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext())
.map(DungeonContext::getMapProcessor).map(a->a.worldPointToRoomPoint(Minecraft.getMinecraft().thePlayer.getPosition()))
.map(a -> DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext().getRoomMapper().get(a));
mechanicBrowserElement.setFocused(false);
if (!dungeonRoomOpt.isPresent()) return;
DungeonRoom dungeonRoom = dungeonRoomOpt.get();
if (!(dungeonRoom.getRoomProcessor() instanceof GeneralRoomProcessor)) return;
((GeneralRoomProcessor) dungeonRoom.getRoomProcessor()).cancel("MECH-BROWSER");
}
public void toggleTooltip(boolean open) {
if (mechanicBrowserTooltip != null) {
if (open) {
mechanicBrowserTooltip.open(this);
} else {
mechanicBrowserTooltip.close();
}
}
}
@Override
public void setBounds(Rectangle bounds) {
super.setBounds(bounds);
Dimension dimension = getEffectiveDimension();
int y = Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT + 4;
scrollablePanel.setBounds(new Rectangle(1,y + 1, dimension.width - 2, dimension.height - y - 2));
scrollablePanel.evalulateContentArea();
if (mechanicBrowserTooltip != null) {
Dimension prefSize = mechanicBrowserTooltip.getPreferredSize();
mechanicBrowserTooltip.setScale(getScale());
mechanicBrowserTooltip.setBounds(new Rectangle(bounds.x + (bounds.x > Minecraft.getMinecraft().displayWidth/2 ? -prefSize.width: bounds.width), latestTooltipDY + bounds.y, prefSize.width, prefSize.height));
}
}
public boolean openGUI() {
return Minecraft.getMinecraft().currentScreen != null
&& Minecraft.getMinecraft().currentScreen instanceof GuiChat && lastRoomUID != null;
}
@Override
public List getChildComponents() {
return openGUI() ? super.getChildComponents() : Collections.emptyList();
}
@Override
public boolean mouseClicked0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int mouseButton) {
selectedID = null;
if (mechanicBrowserTooltip != null) {
mechanicBrowserTooltip.close();
mechanicBrowserTooltip = null;
}
return super.mouseClicked0(absMouseX, absMouseY, relMouseX0, relMouseY0, mouseButton);
}
}