package mhfc.net.client.gui;
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.ENTITY;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.vecmath.Vector2f;
import org.lwjgl.opengl.GL11;
import mhfc.net.client.container.ContainerHunterBench;
import mhfc.net.client.gui.GuiListItem.Alignment;
import mhfc.net.client.quests.MHFCRegQuestVisual;
import mhfc.net.client.util.gui.MHFCGuiUtil;
import mhfc.net.common.core.registry.MHFCEquipementRecipeRegistry;
import mhfc.net.common.crafting.recipes.equipment.EquipmentRecipe;
import mhfc.net.common.crafting.recipes.equipment.EquipmentRecipe.RecipeType;
import mhfc.net.common.item.ItemType;
import mhfc.net.common.item.ItemType.GeneralType;
import mhfc.net.common.tile.TileHunterBench;
import mhfc.net.common.util.lib.MHFCReference;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.client.IItemRenderer.ItemRenderType;
import net.minecraftforge.client.MinecraftForgeClient;
public class GuiHunterBench extends MHFCTabbedGui {
public static final ResourceLocation BURN_BACKGROUND = new ResourceLocation(
MHFCReference.gui_hunterbench_burn_back_tex);
public static final ResourceLocation BURN_FOREGROUND = new ResourceLocation(
MHFCReference.gui_hunterbench_burn_front_tex);
public static final ResourceLocation BURN_TARGET = new ResourceLocation(
MHFCReference.gui_hunterbench_burn_target_tex);
public static final ResourceLocation BACKGROUND = new ResourceLocation(
MHFCReference.gui_hunterbench_back_tex);
public static final ResourceLocation HUNTER_BENCH_COMPLETE = new ResourceLocation(
MHFCReference.gui_hunterbench_complete_tex);
public static final ResourceLocation FUEL_DURATION_MARKER = new ResourceLocation(
MHFCReference.gui_hunterbench_fuel_tex);
static final int maxHeat = 500;
static final int modelRectRelX = 228;
static final int modelRectRelY = 45;
static final int modelRectW = 7 * 18 - 2;
static final int modelRectH = 96;
public class TypeItem extends GuiListItem {
ItemType type;
public TypeItem(ItemType type) {
this.type = type;
}
public ItemType getType() {
return type;
}
@Override
public String getRepresentationString() {
String str = type.getNameString();
return StatCollector.translateToLocal(str);
}
}
public class RecipeItem extends GuiListItem {
String representation;
EquipmentRecipe recipe;
public RecipeItem(EquipmentRecipe recipe) {
this.recipe = recipe;
representation = recipe.getRecipeOutput().getDisplayName();
}
public EquipmentRecipe getRecipe() {
return recipe;
}
@Override
public String getRepresentationString() {
return representation;
}
}
protected abstract class BenchEntityTab extends MHFCGui implements IMHFCTab {
protected TileHunterBench bench;
protected float modelRotX, modelRotY;
protected float maxRotation = 50;
/**
*
* @param start
* Start index of slots on this page, inclusive
* @param end
* End index of slots on this page, exclusive
*/
public BenchEntityTab(TileHunterBench bench) {
this.bench = bench;
resetModelRot();
}
@Override
public void draw(double mousePosX, double mousePosY, float partialTick) {
GL11.glColor4f(1f, 1f, 1f, 1f);
mc.getTextureManager().bindTexture(BACKGROUND);
MHFCGuiUtil.drawTexturedBoxFromBorder(0, 0, zLevel, xSize, ySize, 0, 0, 1f, 1f);
// updateListPositions();
super.draw(mousePosX, mousePosY, partialTick);
fontRendererObj.drawSplitString("Inventory", 6, 12, 500, 0x404040);
GuiHunterBench.this.startCrafting.visible = !bench.isWorking();
GuiHunterBench.this.startCrafting.enabled = bench.canBeginCrafting();
drawItemModelAndHeat(bench, modelRotX, modelRotY);
};
@Override
public boolean handleClick(float relativeX, float relativeY, int button) {
if (isInModelWindow(mouseClickX, mouseClickY) && mouseClickButton == 1) {
resetModelRot();
}
super.handleClick(relativeX, relativeY, button);
return true;
}
private void resetModelRot() {
modelRotX = -50f;
modelRotY = 20f;
}
@Override
protected void itemUpdated(IMHFCGuiItem item) {
if (item instanceof ClickableGuiList<?>) {
listUpdated((ClickableGuiList<?>) item);
}
}
protected void listUpdated(ClickableGuiList<?> list) {}
protected void updateListPositions() {}
@Override
public boolean containsSlot(Slot slot) {
if (slot.inventory == tileEntity || (slot.inventory instanceof InventoryPlayer && slot.slotNumber > 51)) {
return true;
}
return false;
}
@Override
public void updateTab() {
updateListPositions();
}
@Override
public void onClose() {}
@Override
public void onOpen() {
bench.refreshState();
}
@Override
public void handleMovementMouseDown(float mouseX, float mouseY, int button, long timeDiff) {
if (isInModelWindow(mouseClickX, mouseClickY) && mouseClickButton == 0) {
modelRotX += (mouseX - mouseLastX);
modelRotY += (mouseY - mouseLastY);
if (Math.abs(modelRotY) > maxRotation) {
modelRotY = maxRotation * Math.signum(modelRotY);
}
}
super.handleMovementMouseDown(mouseX, mouseY, button, timeDiff);
}
}
/**
* A tab that displays recipes on one recipe type, filtered by their output type. The user can select the output
* type in a list.
*/
protected abstract class FilteredRecipeTab extends BenchEntityTab {
protected RecipeType recipeType;
protected List<ItemType> itemTypes;
protected Map<ItemType, Integer> indicesOfTypes;
protected Map<EquipmentRecipe, Integer> indicesOfRecipes;
protected ClickableGuiList<TypeItem> typeList;
protected ClickableGuiList<RecipeItem> recipeList;
public FilteredRecipeTab(TileHunterBench bench, RecipeType recipeType, List<ItemType> itemTypes) {
super(bench);
this.recipeType = recipeType;
this.itemTypes = itemTypes;
indicesOfRecipes = new HashMap<>();
indicesOfTypes = new HashMap<>();
typeList = new ClickableGuiList<>(70, ySize - 24);
recipeList = new ClickableGuiList<>(70, ySize - 24, 20);
typeList.setAlignment(Alignment.MIDDLE);
initializeTypeList();
addScreenComponent(typeList, new Vector2f(78, 12));
addScreenComponent(recipeList, new Vector2f(153, 12));
if (bench != null) {
EquipmentRecipe recipe = bench.getRecipe();
if (recipe != null) {
RecipeType rectype = recipe.getRecipeType();
ItemType itemtype = recipe.getOutputType();
Integer selectedIndex = indicesOfTypes.get(itemtype);
typeList.setSelected(selectedIndex == null ? -1 : selectedIndex.intValue());
listUpdated(typeList);
if (rectype == recipeType) {
Integer indexOfRecipe = indicesOfRecipes.get(recipe);
recipeList.setSelected(indexOfRecipe == null ? -1 : indexOfRecipe.intValue());
}
}
}
}
private void initializeTypeList() {
for (ItemType itemType : itemTypes) {
indicesOfTypes.put(itemType, typeList.size());
typeList.add(new TypeItem(itemType));
}
}
@Override
protected void listUpdated(ClickableGuiList<?> list) {
ItemType typeOfSelection = getSelectedType();
if (list == typeList) {
recipeList.clear();
fillRecipeList(typeOfSelection);
} else if (list == recipeList) {
RecipeItem recI = recipeList.getSelectedItem();
bench.changeRecipe(recI == null ? null : recI.getRecipe());
}
}
protected ItemType getSelectedType() {
TypeItem selectedItem = typeList.getSelectedItem();
return selectedItem == null ? ItemType.NO_OTHER : selectedItem.getType();
}
@Override
protected void updateListPositions() {
getPosition(typeList).set(78, 12);
getPosition(recipeList).set(153, 12);
}
protected void fillRecipeList(ItemType typeOfSelection) {
Set<EquipmentRecipe> correspondingRecipes = MHFCEquipementRecipeRegistry.getRecipesForType(recipeType);
if (correspondingRecipes == null) {
return;
}
for (EquipmentRecipe rec : correspondingRecipes) {
if (rec.getOutputType() == typeOfSelection) {
indicesOfRecipes.put(rec, recipeList.size());
recipeList.add(new RecipeItem(rec));
}
}
}
}
protected class CraftArmorTab extends FilteredRecipeTab {
public CraftArmorTab(TileHunterBench bench) {
super(bench, RecipeType.ARMOR, ItemType.armorTypes);
}
}
protected class CraftWeaponTab extends FilteredRecipeTab {
public CraftWeaponTab(TileHunterBench bench) {
super(bench, RecipeType.WEAPON, ItemType.weaponTypes);
}
}
protected class CraftUpgradeTab extends FilteredRecipeTab {
public CraftUpgradeTab(TileHunterBench bench) {
super(bench, RecipeType.UPGRADE, ItemType.allTypes);
typeList.setItemWidth(20);
}
}
protected class WeaponTreeTab implements IMHFCTab {
private float mouseX = 0, mouseY = 0;
private int baseX = 0, baseY = 0;
@Override
public void draw(double mousePosX, double mousePosY, float partialTick) {
startCrafting.visible = false;
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_DEPTH_TEST);
drawRect(10, 10, xSize - 10, ySize - 10, 0xFF101010);
drawCenteredString(fontRendererObj, "Not yet implemented", xSize / 2 + baseX, ySize / 2 + baseY, 0xaaaaaa);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glPopMatrix();
}
@Override
public boolean handleClick(float relativeX, float relativeY, int button) {
mouseX = relativeX;
mouseY = relativeY;
if (button == 1) {
baseX = 0;
baseY = 0;
}
return true;
}
@Override
public boolean containsSlot(Slot slot) {
return false;
}
@Override
public void updateTab() {}
@Override
public void onClose() {}
@Override
public void onOpen() {}
@Override
public void handleMovementMouseDown(float mouseX, float mouseY, int button, long timeDiff) {
if (button == 0) {
baseX += mouseX - this.mouseX;
baseY += mouseY - this.mouseY;
}
this.mouseX = mouseX;
this.mouseY = mouseY;
}
@Override
public void handleMouseUp(float mouseX, float mouseY, int button) {
if (button == 0) {
baseX += mouseX - this.mouseX;
baseY += mouseY - this.mouseY;
}
this.mouseX = mouseX;
this.mouseY = mouseY;
}
@Override
public void handleMovement(float mouseX, float mouseY) {
this.mouseX = mouseX;
this.mouseY = mouseY;
}
@Override
public void initializeContext(Minecraft mc) {}
}
public final GuiButton startCrafting;
public final TileHunterBench tileEntity;
public GuiHunterBench(
InventoryPlayer par1InventoryPlayer,
World par2World,
TileHunterBench tileEntity,
int x,
int y,
int z) {
super(new ContainerHunterBench(par1InventoryPlayer, par2World, tileEntity, x, y, z));
this.tileEntity = tileEntity;
this.xSize = 374;
this.ySize = 220;
mc = Minecraft.getMinecraft();
width = MHFCGuiUtil.minecraftWidth(mc);
height = MHFCGuiUtil.minecraftHeight(mc);
this.guiLeft = (width - this.xSize - tabWidth) / 2 + tabWidth;
this.guiTop = (height - this.ySize) / 2;
this.addTab(new CraftArmorTab(tileEntity), "Armor");
this.addTab(new CraftWeaponTab(tileEntity), "Weapons");
this.addTab(new CraftUpgradeTab(tileEntity), "Upgrade");
this.addTab(new WeaponTreeTab(), "Weapon tree");
startCrafting = new GuiButton(0, guiLeft + 228 + (xSize - 228 - 60) / 2, guiTop + 166, 40, 20, "Craft") {
@Override
public void mouseReleased(int p_146118_1_, int p_146118_2_) {
GuiHunterBench.this.tileEntity.beginCrafting();
}
};
selectTab();
}
/**
* Selects a tab based on the currently selected recipe
*/
protected void selectTab() {
int type = 2;
EquipmentRecipe recipe = tileEntity.getRecipe();
if (recipe != null) {
switch (recipe.getRecipeType()) {
case ARMOR:
type = 0;
break;
case WEAPON:
type = 1;
break;
case UPGRADE:
type = 2;
default:
type = 0;
}
}
setTab(type);
}
private void drawItemModelAndHeat(TileHunterBench bench, float modelRotX, float modelRotY) {
if (bench != null) {
ItemStack itemToRender = bench.getStackInSlot(TileHunterBench.resultSlot);
ItemType itemType = ItemType.getTypeOf(itemToRender);
int rectX = modelRectRelX, rectY = modelRectRelY;
int scale = MHFCGuiUtil.guiScaleFactor(mc);
drawItemModel(itemToRender, rectX, rectY, modelRectW, modelRectH, scale, itemType, modelRotX, modelRotY);
drawBenchOverlay(bench, rectX, rectY, modelRectW);
}
}
private boolean isInModelWindow(double mouseClickX, double mouseClickY) {
return (mouseClickX >= modelRectRelX //
&& mouseClickX <= modelRectRelX + modelRectW)
&& (mouseClickY >= modelRectRelY //
&& mouseClickY <= modelRectRelY + modelRectH);
}
private void drawItemModel(
ItemStack itemToRender,
int rectX,
int rectY,
int rectW,
int rectH,
int guiScale,
ItemType itemType,
float modelRotX,
float modelRotY) {
modelRotX /= 2;
modelRotY /= 4;
GL11.glPushMatrix();
drawRect(rectX, rectY, rectX + rectW + 1, rectY + rectH, 0xFF000000);
GL11.glScissor(rectX * guiScale, mc.displayHeight - rectY * guiScale, rectW * guiScale, rectH * guiScale);
GL11.glEnable(GL11.GL_SCISSOR_TEST);
GL11.glClearDepth(1.0f);
GL11.glDisable(GL11.GL_SCISSOR_TEST);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_DEPTH_TEST);
if (itemToRender != null) {
if (itemType.getGeneralType() == GeneralType.ARMOR) {
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GL11.glTranslatef(rectX + rectW / 2, rectY + rectH / 2, 40F);
switch (itemType) {
case ARMOR_HEAD:
GL11.glTranslatef(3f, 15f, 0F);
break;
case ARMOR_BODY:
GL11.glTranslatef(3f, -15f, 0F);
break;
case ARMOR_PANTS:
GL11.glTranslatef(3f, -35f, 0F);
break;
case ARMOR_BOOTS:
GL11.glTranslatef(3f, -55f, 0F);
break;
default:
break;
}
GL11.glRotatef(modelRotX, 0.0f, 1.0f, 0.0f);
GL11.glRotatef(-modelRotY, 1.0f, 0.0f, 0.0f);
float sc = rectH / 2;
GL11.glScalef(sc, sc, -sc);
int armorType = ((net.minecraft.item.ItemArmor) itemToRender.getItem()).armorType;
ResourceLocation loc = RenderBiped.getArmorResource(mc.thePlayer, itemToRender, armorType, null);
mc.getTextureManager().bindTexture(loc);
ModelBiped model = ForgeHooksClient.getArmorModel(mc.thePlayer, itemToRender, armorType, null);
if (model == null) {} else {
model.render(mc.thePlayer, 0, 0, 0, 0, 0, 0.06125f);
GL11.glFrontFace(GL11.GL_CW);
model.render(mc.thePlayer, 0, 0, 0, 0, 0, 0.06125f);
GL11.glFrontFace(GL11.GL_CCW);
}
} else if (itemType.getGeneralType() == GeneralType.WEAPON) {
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GL11.glTranslatef(rectX + rectW / 2, rectY + rectH / 2, 40F);
GL11.glTranslatef(3f, -15f, 0F);
GL11.glRotatef(90F, 1.0f, 0.0f, 0.0f);
modelRotY = Math.min(Math.abs(modelRotY), 30f) * Math.signum(modelRotY);
GL11.glRotatef(modelRotX, 0.0f, 0.0f, -1.0f);
GL11.glRotatef(modelRotY, 0.0f, -1.0f, 0.0f);
float sc = rectH / 8;
GL11.glScalef(sc, -sc, sc);
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(itemToRender, ENTITY);
if (customRenderer == null) {} else {
customRenderer.renderItem(
ItemRenderType.EQUIPPED,
itemToRender,
null,
Minecraft.getMinecraft().thePlayer);
GL11.glFrontFace(GL11.GL_CW);
customRenderer.renderItem(
ItemRenderType.EQUIPPED,
itemToRender,
null,
Minecraft.getMinecraft().thePlayer);
GL11.glFrontFace(GL11.GL_CCW);
}
}
}
GL11.glPopMatrix();
}
private void drawBenchOverlay(TileHunterBench bench, int rectX, int rectY, int rectW) {
// Draw the background required heat indicator
final int burnHeight = 96;
final int completeWidth = 34;
int heat;
float burnTexVDiff;
float burnTexV;
int burnTexHeight;
int burnTexY;
// Draw the foreground current heat indicator
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
mc.getTextureManager().bindTexture(BURN_BACKGROUND);
heat = Math.min(bench.getHeatStrength(), maxHeat);
burnTexVDiff = (float) (heat) / maxHeat;
burnTexV = 1.0f - burnTexVDiff;
burnTexHeight = (int) (burnTexVDiff * burnHeight);
burnTexY = rectY + burnHeight - burnTexHeight;
MHFCGuiUtil.drawTexturedRectangle(
rectX + rectW + 4,
burnTexY,
10,
burnTexHeight,
0.0f,
burnTexV,
1.0f,
burnTexVDiff);
if (bench.getRecipe() != null) {
GL11.glLineWidth(1f);
heat = bench.getRecipe().getRequiredHeat();
heat = Math.min(heat, maxHeat);
burnTexVDiff = (float) (heat) / maxHeat;
burnTexHeight = (int) (burnTexVDiff * burnHeight);
burnTexY = rectY + burnHeight - burnTexHeight;
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glLineWidth(2.0f);
GL11.glBegin(GL11.GL_LINES);
GL11.glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
GL11.glVertex3f(rectX + rectW + 4, burnTexY + 0.7f, this.zLevel);
GL11.glVertex3f(rectX + rectW + 14, burnTexY + 0.7f, this.zLevel);
GL11.glEnd();
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Draw heat target
mc.getTextureManager().bindTexture(BURN_TARGET);
heat = Math.min(TileHunterBench.getItemHeat(bench.getStackInSlot(TileHunterBench.fuelSlot)), maxHeat);
if (heat > 0) {
burnTexVDiff = (float) (heat) / maxHeat;
burnTexHeight = (int) (burnTexVDiff * burnHeight);
burnTexY = rectY + burnHeight - burnTexHeight;
MHFCGuiUtil.drawTexturedBoxFromBorder(rectX + rectW + 4, burnTexY - 1, this.zLevel, 10, 3, 0);
}
// Draw front layer, the border
mc.getTextureManager().bindTexture(BURN_FOREGROUND);
MHFCGuiUtil.drawTexturedBoxFromBorder(rectX + rectW + 4, rectY - 1, this.zLevel, 10, burnHeight + 1, 0);
// draw the heat length indicator
mc.getTextureManager().bindTexture(FUEL_DURATION_MARKER);
float remaining = bench.getHeatLength() / (float) bench.getHeatLengthOriginal();
if (Float.isInfinite(remaining)) {
remaining = 0;
}
int remain = (int) Math.ceil(remaining * 14);
remaining = remain / 17f;
Tessellator t = Tessellator.instance;
t.startDrawingQuads();
t.addVertexWithUV(353, 159 - remain, this.zLevel, 0f, 14f / 17 - remaining);
t.addVertexWithUV(353, 159, this.zLevel, 0f, 14f / 17);
t.addVertexWithUV(370, 159, this.zLevel, 1f, 14f / 17);
t.addVertexWithUV(370, 159 - remain, this.zLevel, 1f, 14f / 17 - remaining);
t.draw();
// draw the completition gauge
if (bench.getRecipe() != null) {
float completition = bench.getItemSmeltDuration() / (float) bench.getRecipe().getDuration();
int complete = (int) (completition * completeWidth);
completition = complete / (float) completeWidth;
mc.getTextureManager().bindTexture(HUNTER_BENCH_COMPLETE);
MHFCGuiUtil.drawTexturedBoxFromBorder(
298,
145,
this.zLevel,
(int) (completition * completeWidth),
17,
0,
0,
completition,
1f);
}
}
@Override
public void initGui() {
buttonList.add(startCrafting);
super.initGui();
this.guiLeft = (this.width - this.xSize - tabWidth) / 2 + tabWidth;
this.guiTop = (this.height - this.ySize) / 2;
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
@Override
protected void drawTabBackgroundLayer() {
GL11.glColor4f(1f, 1f, 1f, 1f);
this.mc.getTextureManager().bindTexture(MHFCRegQuestVisual.QUEST_BOARD_BACKGROUND);
int posX = guiLeft;
int posY = guiTop;
MHFCGuiUtil.drawTexturedBoxFromBorder(posX, posY, this.zLevel, this.xSize, this.ySize, 0, 0, 1f, 1f);
}
@Override
public void updateScreen() {
super.updateScreen();
startCrafting.xPosition = guiLeft + 228 + (xSize - 228 - 60) / 2;
startCrafting.yPosition = guiTop + 166;
}
}