diff --git a/src/main/java/tconstruct/client/TProxyClient.java b/src/main/java/tconstruct/client/TProxyClient.java index d94d884e182..e9fdd03ee7e 100644 --- a/src/main/java/tconstruct/client/TProxyClient.java +++ b/src/main/java/tconstruct/client/TProxyClient.java @@ -16,7 +16,6 @@ import org.w3c.dom.Document; -import cpw.mods.fml.common.Loader; import mantle.client.SmallFontRenderer; import mantle.lib.client.MantleClientRegistry; import tconstruct.TConstruct; @@ -57,15 +56,16 @@ public void registerRenderer() { public static Document volume2; public static Document smelter; public static Document weaponry; + public static Document materialsandyou; public static ManualInfo manualData; public void readManuals() { initManualIcons(); initManualRecipes(); initManualPages(); - if (!Loader.isModLoaded("dreamcraft")) { - readTinkersConstructManuals(); - } + // if (!Loader.isModLoaded("dreamcraft")) { + readTinkersConstructManuals(); + // } } private void readTinkersConstructManuals() { @@ -77,6 +77,7 @@ private void readTinkersConstructManuals() { Document volume2_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/materials.xml", dbFactory); Document smelter_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/smeltery.xml", dbFactory); Document weaponry_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/weaponry.xml", dbFactory); + Document materialsandyou_cl = readManual("/assets/tinker/manuals/materialsandyou.xml", dbFactory); diary = diary_cl != null ? diary_cl : readManual("/assets/tinker/manuals/en_US/diary.xml", dbFactory); volume1 = volume1_cl != null ? volume1_cl : readManual("/assets/tinker/manuals/en_US/firstday.xml", dbFactory); @@ -84,6 +85,7 @@ private void readTinkersConstructManuals() { smelter = smelter_cl != null ? smelter_cl : readManual("/assets/tinker/manuals/en_US/smeltery.xml", dbFactory); weaponry = weaponry_cl != null ? weaponry_cl : readManual("/assets/tinker/manuals/en_US/weaponry.xml", dbFactory); + materialsandyou = materialsandyou_cl; manualData = new ManualInfo(); } diff --git a/src/main/java/tconstruct/client/pages/NavigationPage.java b/src/main/java/tconstruct/client/pages/NavigationPage.java new file mode 100644 index 00000000000..f82e837123f --- /dev/null +++ b/src/main/java/tconstruct/client/pages/NavigationPage.java @@ -0,0 +1,157 @@ +package tconstruct.client.pages; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import mantle.books.BookData; +import tconstruct.TConstruct; +import tconstruct.library.client.TConstructClientRegistry; +import tconstruct.library.util.IToolPart; +import tconstruct.library.util.TiCBookData; +import tconstruct.library.util.TiCGuiManual; +import tconstruct.library.util.TiCNavigationButton; +import tconstruct.library.util.TiCNavigationButton.ButtonSize; +import tconstruct.util.FontColorHelper; +import tconstruct.util.McTextFormatter; + +public class NavigationPage extends TiCBookPage { + + private static final String namePrefix = "tconstruct.manual.materialsandyou.navigation."; + + private ButtonSize BS; + + private String title; + int eachRow; + + @Override + public void readPageFromXML(Element element) { + this.pageButtonList = new ArrayList<>(); + + String size = element.getAttribute("size"); + this.BS = ButtonSize.getSize(size); + + String eachRowString = element.getAttribute("capacity"); + this.eachRow = eachRowString.length() != 0 ? Integer.parseInt(eachRowString) : 5; + + String name = element.getAttribute("name"); + if (StatCollector.canTranslate(namePrefix + name)) { + this.title = StatCollector.translateToLocal(namePrefix + name); + } else { + this.title = name; + } + + NodeList buttonList = element.getElementsByTagName("button"); + int length = buttonList.getLength(); + for (int idx = 0; idx < length; idx++) { + Element b = (Element) buttonList.item(idx); + + String color = b.getAttribute("color"); + String naviTo = b.getAttribute("to"); + String tempText = b.getElementsByTagName("text").item(0).getTextContent(); + if (StatCollector.canTranslate(tempText)) tempText = StatCollector.translateToLocal(tempText); + + String iconStr = b.getElementsByTagName("icon").item(0).getTextContent(); + if (iconStr.startsWith("material_")) { + ItemStack[] iconStacks = (ItemStack[]) TConstructClientRegistry.getManualIcon(iconStr); + iconStacks = Arrays.asList(iconStacks).stream().filter(i -> !(i.getItem() instanceof IToolPart)) + .collect(Collectors.toList()).toArray(new ItemStack[0]); + this.pageButtonList + .add( + new TiCNavigationButton( + 0, + this.BS, + iconStacks, + naviTo, + tempText, + this, + color.length() != 0 ? FontColorHelper + .adjustForegroundKeepHue(BACKGROUNDCOLOR, Integer.parseInt(color)) + : 0x000000)); + } else { + ItemStack iconStack = TConstructClientRegistry.getOrRegisterManualIcon(iconStr); + this.pageButtonList.add(new TiCNavigationButton(0, this.BS, iconStack, tempText, naviTo, this)); + } + } + } + + public static int ceilDiv(int x, int y) { + final int q = x / y; + // if the signs are the same and modulo not zero, round up + if ((x ^ y) >= 0 && (q * y != x)) { + return q + 1; + } + return q; + } + + public void updateButtonPositionAndRender(int startX, int startY, float scale, int mouseX, int mouseY, + List parentButtonList) { + if (title != null) this.drawStrCenterAt( + McTextFormatter.addUnderLine(title), + startX + PAGECONTENTWIDTH / 2, + startY + 4, + 1.0f, + 0x000000); + + int middleX = startX + PAGECONTENTWIDTH / 2; + int middleY = startY + PAGECONTENTHEIGHT / 2; + + int buttonWidth = (int) (TiCNavigationButton.defaultWidth * BS.multi); + int buttonHeight = (int) (TiCNavigationButton.defaultHeight * BS.multi); + // int buttonGap = buttonWidth / 8; + int buttonGap = 5; + + int buttonRows = ceilDiv(this.pageButtonList.size(), this.eachRow); + + int buttonsGroupHeight = buttonRows * buttonHeight + (buttonRows - 1) * buttonGap; + int buttonsGroupWidth = this.eachRow * buttonWidth + (this.eachRow - 1) * buttonGap; + + int buttonsGroupStartX = middleX - buttonsGroupWidth / 2; + int buttonsGroupStartY = middleY - buttonsGroupHeight / 2; + + for (int idx = 0; idx < this.pageButtonList.size(); idx++) { + TiCNavigationButton b = (TiCNavigationButton) this.pageButtonList.get(idx); + int row = idx / this.eachRow; + int column = idx % this.eachRow; + + int buttonX = buttonsGroupStartX + column * (buttonWidth + buttonGap); + int buttonY = buttonsGroupStartY + row * (buttonHeight + buttonGap); + + b.id = idx + parentButtonList.size(); + b.xPosition = (int) (buttonX * scale); + b.yPosition = (int) (buttonY * scale); + b.drawButtonWithScale(manual.mc, mouseX, mouseY, scale, manual.fonts); + } + + if (parentButtonList != null) { + parentButtonList.addAll(this.pageButtonList); + } + } + + @Override + public void actionPerformed(GuiButton button, BookData d) { + TiCNavigationButton b = (TiCNavigationButton) button; + if (d instanceof TiCBookData tcbd) { + int pageIndex = tcbd.getIndexFromName(b.target); + Item item = b.renderStack[b.counter % b.renderStack.length].getItem(); + + TConstruct.logger.info(item + " is clicked"); + if (pageIndex != -1) { + ((TiCGuiManual) manual).setCurrentPage(pageIndex); + } else { + TConstruct.logger.error("There's no page name " + b.target); + } + } + + } + +} diff --git a/src/main/java/tconstruct/client/pages/TiCBookPage.java b/src/main/java/tconstruct/client/pages/TiCBookPage.java new file mode 100644 index 00000000000..7298b6a9454 --- /dev/null +++ b/src/main/java/tconstruct/client/pages/TiCBookPage.java @@ -0,0 +1,120 @@ +package tconstruct.client.pages; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.item.ItemStack; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import mantle.books.BookData; +import mantle.client.pages.BookPage; +import tconstruct.library.util.ItemStackWithPosition; +import tconstruct.library.util.TiCGuiButton; +import tconstruct.library.util.WidgetsHasTooltips; + +public abstract class TiCBookPage extends BookPage { + + public static final int PAGECONTENTHEIGHT = 165; + + // outer gap is 16 inner gap is 5, 185 + 16 + 5 = 206 + public static final int PAGECONTENTWIDTH = 185; + + public static final int BACKGROUNDCOLOR = 0xFFFAEE; + + List pageButtonList; + public List widgetsList = new ArrayList<>(); + + public void updateButtonPositionAndRender(int startX, int startY, float scale, int mouseX, int mouseY, + List parentButtonList) { + + // just for debug, draw a rect on page range to see where is the border + // Gui.drawRect(startX, startY, startX + PAGECONTENTWIDTH, startY + PAGECONTENTHEIGHT, 0xAAAAAAAA); + + updateButtonPosition(startX, startY, scale, mouseX, mouseY, parentButtonList); + render(startX, startY, scale, mouseX, mouseY, parentButtonList); + } + + public void updateButtonPosition(int startX, int startY, float scale, int mouseX, int mouseY, + List parentButtonList) {} + + public void render(int startX, int startY, float scale, int mouseX, int mouseY, List parentButtonList) {} + + @Override + public void renderContentLayer(int localwidth, int localheight, boolean isTranslatable) { + this.updateButtonPositionAndRender(localheight, localheight, 1.0f, 0, 0, null); + } + + public void actionPerformed(GuiButton button, BookData b) {} + + void drawStrAt(String str, int X, int Y, float scale) { + drawStrAt(str, X, Y, scale, 0x000000); + } + + void drawStrAt(String str, int X, int Y, float scale, int color) { + manual.fonts.drawString(str, (int) (X / scale), (int) (Y / scale), color); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + void drawStrCenterAt(String str, int X, int Y, float scale, int color) { + manual.fonts.drawString( + str, + (int) (X / scale - manual.fonts.getStringWidth(str) / 2), + (int) ((Y - manual.fonts.FONT_HEIGHT / 2) / scale), + color); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + void renderItemStackIntoPage(ItemStack stack, int x, int y) { + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + GL11.glPushMatrix(); + manual.renderitem.renderItemAndEffectIntoGUI(manual.fonts, manual.getMC().renderEngine, stack, x, y); + if (stack.stackSize > 1) manual.renderitem.renderItemOverlayIntoGUI( + manual.fonts, + manual.getMC().renderEngine, + stack, + x, + y, + String.valueOf(stack.stackSize)); + GL11.glPopMatrix(); + GL11.glPopAttrib(); + } + + void beforeRenderItem() { + beforeRenderItem(2.0F); + } + + void beforeRenderItem(float scale) { + beforeRenderItem(scale, 100); + } + + void beforeRenderItem(float scale, int z) { + GL11.glPushMatrix(); + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + GL11.glScalef(scale, scale, 2.0F); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + RenderHelper.enableGUIStandardItemLighting(); + manual.renderitem.zLevel = z; + } + + void afterRenderItem() { + afterRenderItem(2.0F); + } + + void afterRenderItem(float scale) { + manual.renderitem.zLevel = 0; + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopAttrib(); + GL11.glPopMatrix(); + } + + void renderItemStackIntoPage(ItemStack stack, int x, int y, float scale) { + renderItemStackIntoPage(stack, x, y); + this.widgetsList.add(new ItemStackWithPosition(stack, x, y, scale)); + } + +} diff --git a/src/main/java/tconstruct/client/pages/TiCCoverPage.java b/src/main/java/tconstruct/client/pages/TiCCoverPage.java new file mode 100644 index 00000000000..cd21725b668 --- /dev/null +++ b/src/main/java/tconstruct/client/pages/TiCCoverPage.java @@ -0,0 +1,54 @@ +package tconstruct.client.pages; + +import net.minecraft.util.StatCollector; + +import org.lwjgl.opengl.GL11; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import mantle.client.pages.BookPage; + +public class TiCCoverPage extends BookPage { + + String[] innerText; + + @Override + public void readPageFromXML(Element element) { + NodeList nodes = element.getElementsByTagName("text"); + String tempText = nodes.item(0).getTextContent(); + if (StatCollector.canTranslate(tempText)) tempText = StatCollector.translateToLocal(tempText); + innerText = tempText.split("\\\\n"); + } + + private void drawStrCenterAt(String str, int X, int Y, float scale, int color) { + manual.fonts.drawString( + str, + (int) (X / scale - manual.fonts.getStringWidth(str) / 2), + (int) ((Y - manual.fonts.FONT_HEIGHT / 2) / scale), + color); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + } + + @Override + public void renderContentLayer(int startX, int startY, boolean isTranslatable) { + + int cousorX = TiCBookPage.PAGECONTENTWIDTH / 2; + int cousorY = TiCBookPage.PAGECONTENTHEIGHT * 3 / 7; + + float scale = 2.5f; + GL11.glScalef(scale, scale, 1.0f); + this.drawStrCenterAt(innerText[0], startX + cousorX, startY + cousorY, scale, 0x000000); + cousorY += manual.fonts.FONT_HEIGHT * scale; + GL11.glScalef(1.0f / scale, 1.0f / scale, 1.0f); + + scale = 1.0f; + GL11.glScalef(scale, scale, 1.0f); + this.drawStrCenterAt(innerText[1], startX + cousorX, startY + cousorY, scale, 0x000000); + cousorY += manual.fonts.FONT_HEIGHT * scale; + this.drawStrCenterAt(innerText[2], startX + cousorX, startY + cousorY, scale, 0x000000); + cousorY += manual.fonts.FONT_HEIGHT * scale; + GL11.glScalef(1.0f / scale, 1.0f / scale, 1.0f); + + } + +} diff --git a/src/main/java/tconstruct/client/pages/TiCCraftingPage.java b/src/main/java/tconstruct/client/pages/TiCCraftingPage.java new file mode 100644 index 00000000000..62454644557 --- /dev/null +++ b/src/main/java/tconstruct/client/pages/TiCCraftingPage.java @@ -0,0 +1,277 @@ +package tconstruct.client.pages; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; + +import org.lwjgl.opengl.GL11; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import mantle.books.BookData; +import tconstruct.library.client.TConstructClientRegistry; +import tconstruct.library.util.TiCTurnPageButton; +import tconstruct.library.util.TiCTurnPageButton.ButtonType; +import tconstruct.util.McTextFormatter; +import tconstruct.util.TiCRecipeHolder; +import tconstruct.util.TiCRecipeHolder.RecipeType; + +public class TiCCraftingPage extends TiCBookPage { + + String title; + String desc; + TiCRecipeHolder[] recipes; + int maxRecipesSize = 1; + + int selectedIdx; + TiCTurnPageButton previousRecipeButton; + TiCTurnPageButton nextRecipeButton; + + private static final ResourceLocation craftingTableBackground = new ResourceLocation( + "mantle", + "textures/gui/bookcrafting.png"); + private static final ResourceLocation furnaceBackground = new ResourceLocation( + "mantle", + "textures/gui/bookfurnace.png"); + + private static final ResourceLocation toolStationForgeBackground = new ResourceLocation( + "tinker", + "textures/gui/bookmodifyandstation.png"); + + long lastUpdate; + int counter; + + final static ItemStack fuel = TConstructClientRegistry.getOrRegisterManualIcon("minecraft:coal"); + final static int[][] toolStationOrForgePosition = new int[][] { { 28, 28 }, { 28, 3 }, { 3, 24 }, { 7, 50 }, + { 49, 50 }, { 53, 24 } }; + + final static String manualLangPrefix = "tconstruct.manual.materialsandyou."; + + @Override + public void readPageFromXML(Element element) { + this.pageButtonList = new ArrayList<>(); + NodeList nodes = element.getElementsByTagName("icon"); + if (nodes != null) { + String textContent = nodes.item(0).getTextContent(); + this.recipes = TConstructClientRegistry.getOrRegisterRecipeIcon(textContent); + this.title = recipes[0].outputStack.getDisplayName(); + this.desc = StatCollector.canTranslate(manualLangPrefix + textContent) + ? StatCollector.translateToLocal(manualLangPrefix + textContent) + : null; + } + this.selectedIdx = 0; + + this.pageButtonList + .add(this.previousRecipeButton = new TiCTurnPageButton(0, 0, 0, ButtonType.previousPage, this)); + this.pageButtonList.add(this.nextRecipeButton = new TiCTurnPageButton(0, 0, 0, ButtonType.nextPage, this)); + + this.lastUpdate = System.currentTimeMillis(); + this.counter = 0; + + } + + @Override + public void updateButtonPosition(int startX, int startY, float scale, int mouseX, int mouseY, + List parentButtonList) { + this.previousRecipeButton.id = parentButtonList.size(); + this.nextRecipeButton.id = parentButtonList.size() + 1; + + this.previousRecipeButton.xPosition = (int) ((startX + this.previousRecipeButton.getWidth() * 0.5f) * scale); + this.nextRecipeButton.xPosition = (int) ((startX + PAGECONTENTWIDTH - this.nextRecipeButton.getWidth() * 1.5f) + * scale); + + this.previousRecipeButton.yPosition = (int) ((startY + 15) * scale); + this.nextRecipeButton.yPosition = (int) ((startY + 15) * scale); + + this.updateVisible(); + } + + @Override + public void render(int startX, int startY, float scale, int mouseX, int mouseY, List parentButtonList) { + this.maxRecipesSize = 1; + this.widgetsList.clear(); + + this.previousRecipeButton.drawButtonWithScale(manual.mc, mouseX, mouseY, scale); + this.nextRecipeButton.drawButtonWithScale(manual.mc, mouseX, mouseY, scale); + + if (this.selectedIdx >= 0 && this.selectedIdx < this.recipes.length) { + + TiCRecipeHolder selectedRecipe = this.recipes[this.selectedIdx]; + + String craftingType = StatCollector + .translateToLocal("tconstruct.manual.materialsandyou.recipetype." + selectedRecipe.recipeType.type); + + // update displayed item + if (this.maxRecipesSize > 1 && System.currentTimeMillis() - lastUpdate > 1000) { + lastUpdate = System.currentTimeMillis(); + counter++; + if (counter >= this.maxRecipesSize) counter = 0; + } + + if (title != null) this.drawStrCenterAt( + McTextFormatter.addUnderLine(title), + startX + PAGECONTENTWIDTH / 2, + startY + 4, + 1.0f, + 0x000000); + this.drawStrCenterAt(craftingType, startX + PAGECONTENTWIDTH / 2, startY + 15, 1.0f, 0x000000); + + if (selectedRecipe.recipeType == RecipeType.Furnace) { + renderFurnaceRecipe(startX, startY, selectedRecipe, scale); + } else if (selectedRecipe.recipeType == RecipeType.ToolForge + || selectedRecipe.recipeType == RecipeType.ToolStation) { + renderToolStationOrForgeRecipe(startX, startY, selectedRecipe, scale); + } else { + switch (selectedRecipe.recipeSize) { + case 2 -> render22CraftingRecipe(startX, startY, selectedRecipe, scale); + case 3 -> render33CraftingRecipe(startX, startY, selectedRecipe, scale); + } + } + + } + + if (parentButtonList != null) { + parentButtonList.addAll(pageButtonList); + } + } + + private void render22CraftingRecipe(int startX, int startY, TiCRecipeHolder selectedRecipe, float scale) { + ItemStack[][] inputStacks = selectedRecipe.inputStacks; + ItemStack outputStack = selectedRecipe.outputStack; + + manual.getMC().getTextureManager().bindTexture(craftingTableBackground); + manual.drawTexturedModalRect(startX + 8, startY + 46, 0, 116, 154, 78); + + beforeRenderItem(); + + renderItemStackIntoPage(outputStack, (startX + 126) / 2, (startY + 68) / 2, 2 * scale); + + for (int i = 0; i < inputStacks.length; i++) { + if (inputStacks[i] != null && inputStacks[i][0] != null) { + ItemStack renderStack = inputStacks[i][this.counter % inputStacks[i].length]; + renderItemStackIntoPage( + renderStack, + (startX + 14 + 36 * (i % 2)) / 2, + (startY + 36 * (i / 2) + 52) / 2, + 2 * scale); + } + } + + afterRenderItem(); + } + + private void render33CraftingRecipe(int startX, int startY, TiCRecipeHolder selectedRecipe, float scale) { + ItemStack[][] inputStacks = selectedRecipe.inputStacks; + ItemStack outputStack = selectedRecipe.outputStack; + + int biasY = startY + 28; + + manual.getMC().getTextureManager().bindTexture(craftingTableBackground); + manual.drawTexturedModalRect(startX, biasY, 0, 0, 183, 114); + + beforeRenderItem(); + + renderItemStackIntoPage(outputStack, (startX + 146) / 2, (biasY + 41) / 2, 2 * scale); + + for (int i = 0; i < inputStacks.length; i++) { + if (inputStacks[i] != null && inputStacks[i][0] != null) { + ItemStack renderStack = inputStacks[i][this.counter % inputStacks[i].length]; + renderItemStackIntoPage( + renderStack, + (startX + 6 + 36 * (i % 3)) / 2, + (biasY + 7 + 36 * (i / 3)) / 2, + 2 * scale); + } + } + + afterRenderItem(); + } + + private void renderFurnaceRecipe(int startX, int startY, TiCRecipeHolder selectedRecipe, float scale) { + ItemStack[][] inputStacks = selectedRecipe.inputStacks; + ItemStack outputStack = selectedRecipe.outputStack; + + manual.getMC().getTextureManager().bindTexture(furnaceBackground); + manual.drawTexturedModalRect(startX + 32, startY + 32, 0, 0, 111, 114); + + beforeRenderItem(); + + renderItemStackIntoPage(fuel, (startX + 38) / 2, (startY + 110) / 2, scale); + renderItemStackIntoPage(outputStack, (startX + 106) / 2, (startY + 74) / 2, 2 * scale); + renderItemStackIntoPage(inputStacks[0][0], (startX + 38) / 2, (startY + 38) / 2, 2 * scale); + + afterRenderItem(); + } + + private void renderToolStationOrForgeRecipe(int startX, int startY, TiCRecipeHolder selectedRecipe, float scale) { + ItemStack[][] inputStacks = selectedRecipe.inputStacks; + ItemStack outputStack = selectedRecipe.outputStack; + + if (this.desc != null) { + manual.fonts.drawSplitString(this.desc, startX + 8, startY + 20, PAGECONTENTWIDTH - 16, 0); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + int recipeStartX = startX + PAGECONTENTWIDTH - 72 - 5; + int recipeStartY = startY + PAGECONTENTHEIGHT - 69 - 5; + + manual.getMC().getTextureManager().bindTexture(toolStationForgeBackground); + manual.drawTexturedModalRect( + recipeStartX + 12, + recipeStartY + 12, + 208, + (selectedRecipe.recipeType == RecipeType.ToolForge ? 48 : 0), + 48, + 48); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.85F); + manual.drawTexturedModalRect(recipeStartX, recipeStartY, 0, 0, 72, 69); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + int idx = 0; + + beforeRenderItem(1.0F); + + renderItemStackIntoPage( + outputStack, + recipeStartX + toolStationOrForgePosition[idx][0], + recipeStartY + toolStationOrForgePosition[idx][1], + scale); + idx += 1; + + for (ItemStack[] l : inputStacks) { + if (l.length != 0 && l[0] != null) { + renderItemStackIntoPage( + l[0], + recipeStartX + toolStationOrForgePosition[idx][0], + recipeStartY + toolStationOrForgePosition[idx][1], + scale); + idx += 1; + } + } + + afterRenderItem(1.0F); + } + + @Override + public void actionPerformed(GuiButton button, BookData d) { + TiCTurnPageButton b = (TiCTurnPageButton) button; + if (b == this.previousRecipeButton) { + this.selectedIdx -= 1; + } else if (b == this.nextRecipeButton) { + this.selectedIdx += 1; + } + this.selectedIdx = Math.max(0, Math.min(this.recipes.length - 1, selectedIdx)); + this.updateVisible(); + } + + void updateVisible() { + this.previousRecipeButton.visible = this.selectedIdx != 0; + this.nextRecipeButton.visible = this.recipes.length != 0 && this.selectedIdx != this.recipes.length - 1; + } + +} diff --git a/src/main/java/tconstruct/client/pages/TiCMaterialPage.java b/src/main/java/tconstruct/client/pages/TiCMaterialPage.java new file mode 100644 index 00000000000..6d51afca3a8 --- /dev/null +++ b/src/main/java/tconstruct/client/pages/TiCMaterialPage.java @@ -0,0 +1,227 @@ +package tconstruct.client.pages; + +import java.util.List; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import org.lwjgl.opengl.GL11; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import tconstruct.library.TConstructRegistry; +import tconstruct.library.client.TConstructClientRegistry; +import tconstruct.library.tools.ArrowMaterial; +import tconstruct.library.tools.BowMaterial; +import tconstruct.library.tools.ToolMaterial; +import tconstruct.library.util.HarvestLevels; +import tconstruct.library.util.StringWithPosition; +import tconstruct.modifiers.tools.ModReinforced; +import tconstruct.util.FontColorHelper; +import tconstruct.util.McTextFormatter; + +public class TiCMaterialPage extends TiCBookPage { + + public ToolMaterial tm; + public ArrowMaterial am; + public BowMaterial bm; + + public ItemStack[] materialStacks; + + private static final String namePrefix = "tconstruct.manual.materialsandyou.material."; + + String materialExtraDesc = null; + + long lastUpdate; + int counter; + + @Override + public void readPageFromXML(Element element) { + NodeList nodes = element.getElementsByTagName("text"); + if (nodes != null) { + String materialName = nodes.item(0).getTextContent(); + tm = TConstructRegistry.getMaterial(materialName); + + String materialId = nodes.item(1).getTextContent(); + if (materialId.length() != 0) { + int id = Integer.parseInt(materialId); + am = TConstructRegistry.getArrowMaterial(id); + bm = TConstructRegistry.getBowMaterial(id); + } + + materialStacks = (ItemStack[]) TConstructClientRegistry.getManualIcon("material_" + materialName); + + if (StatCollector.canTranslate(namePrefix + materialName)) + this.materialExtraDesc = StatCollector.translateToLocal(namePrefix + materialName); + } + lastUpdate = System.currentTimeMillis(); + } + + @Override + public void render(int startX, int startY, float scale, int mouseX, int mouseY, List parentButtonList) { + this.widgetsList.clear(); + if (tm != null) this.drawStrCenterAt( + McTextFormatter.addBold(McTextFormatter.addUnderLine(tm.localizedName())), + startX + PAGECONTENTWIDTH / 2, + startY + 4, + 1.0f, + FontColorHelper.adjustForegroundKeepHue(BACKGROUNDCOLOR, tm.primaryColor())); + + GL11.glPushMatrix(); + GL11.glScaled(1.05f, 1.05f, 1.0f); + + float realScale = scale * 1.05f; + int stringStartX = (int) ((startX + (this.side == 0 ? 30 : 10)) * realScale); + int stringStartY = (int) ((startY + 20) * realScale); + + int lineHeight = (int) (manual.fonts.FONT_HEIGHT * realScale); + + String str = StatCollector.translateToLocalFormatted( + "gui.partcrafter.durability", + McTextFormatter.addDarkGreen(String.valueOf(tm.durability))); + drawStrAt(str, stringStartX, stringStartY, realScale); + if (StatCollector.canTranslate("gui.partcrafter.durability.desc")) addNewTooltipsString( + StatCollector.translateToLocal("gui.partcrafter.durability.desc"), + stringStartX, + stringStartY, + manual.fonts.getStringWidth(str) * realScale, + lineHeight); + stringStartY += lineHeight; + + str = StatCollector.translateToLocalFormatted( + "gui.partcrafter.handlemodifier", + McTextFormatter.addGold(String.valueOf(tm.handleModifier))); + drawStrAt(str, stringStartX, stringStartY, realScale); + if (StatCollector.canTranslate("gui.partcrafter.handlemodifier.desc")) addNewTooltipsString( + StatCollector.translateToLocal("gui.partcrafter.handlemodifier.desc"), + stringStartX, + stringStartY, + manual.fonts.getStringWidth(str) * realScale, + lineHeight); + stringStartY += lineHeight; + + str = StatCollector.translateToLocalFormatted( + "gui.partcrafter.miningspeed", + McTextFormatter.addBlue(String.valueOf(tm.miningspeed / 100F))); + drawStrAt(str, stringStartX, stringStartY, realScale); + if (StatCollector.canTranslate("gui.partcrafter.miningspeed.desc")) addNewTooltipsString( + StatCollector.translateToLocal("gui.partcrafter.miningspeed.desc"), + stringStartX, + stringStartY, + manual.fonts.getStringWidth(str) * realScale, + lineHeight); + stringStartY += lineHeight; + + str = StatCollector.translateToLocalFormatted( + "gui.partcrafter.mininglevel", + HarvestLevels.getHarvestLevelName(tm.harvestLevel)); + drawStrAt(str, stringStartX, stringStartY, realScale); + if (StatCollector.canTranslate("gui.partcrafter.mininglevel.desc")) addNewTooltipsString( + StatCollector.translateToLocal("gui.partcrafter.mininglevel.desc"), + stringStartX, + stringStartY, + manual.fonts.getStringWidth(str) * realScale, + lineHeight); + stringStartY += lineHeight; + + str = StatCollector.translateToLocalFormatted( + "gui.partcrafter.attack", + McTextFormatter.addDarkRed(String.valueOf(tm.attack))); + drawStrAt(str, stringStartX, stringStartY, realScale); + if (StatCollector.canTranslate("gui.partcrafter.attack.desc")) addNewTooltipsString( + StatCollector.translateToLocal("gui.partcrafter.attack.desc"), + stringStartX, + stringStartY, + manual.fonts.getStringWidth(str) * realScale, + lineHeight); + stringStartY += (lineHeight * 1.2); + + if (tm.reinforced > 0) { + drawStrAt( + McTextFormatter.addDarkPurple( + McTextFormatter.addUnderLine(ModReinforced.getReinforcedString(tm.reinforced))), + stringStartX, + stringStartY, + realScale); + + String reinforcedDesc = StatCollector.translateToLocal("tool.reinforced.desc"); + addNewTooltipsString( + reinforcedDesc, + stringStartX, + stringStartY, + manual.fonts.getStringWidth(ModReinforced.getReinforcedString(tm.reinforced)) * realScale, + lineHeight); + + stringStartY += (lineHeight * 1.2); + } + + String abilityStr = null; + String abilityDesc = null; + if (tm.shoddy() != 0) { + abilityStr = McTextFormatter.addUnderLine(tm.ability() + ": " + Math.abs(tm.shoddy())); + if (tm.shoddy() > 0) { + abilityStr = McTextFormatter.addDarkRed(abilityStr); + } else { + abilityStr = McTextFormatter.addDarkGreen(abilityStr); + } + abilityDesc = tm.abilityDesc(); + } else if (tm.ability().length() != 0) { + abilityStr = tm.style() + McTextFormatter.addUnderLine(tm.ability()); + abilityDesc = tm.abilityDesc(); + } + + if (abilityStr != null) { + drawStrAt(abilityStr, stringStartX, stringStartY, realScale); + if (abilityDesc.length() != 0) { + addNewTooltipsString( + abilityDesc, + stringStartX, + stringStartY, + manual.fonts.getStringWidth(abilityStr) * realScale, + lineHeight); + } else { + addNewTooltipsString( + StatCollector.translateToLocalFormatted("tool.nodesc", tm.ability()), + stringStartX, + stringStartY, + manual.fonts.getStringWidth(abilityStr) * realScale, + lineHeight); + } + stringStartY += (lineHeight * 1.2); + + } + + GL11.glPopMatrix(); + + beforeRenderItem(1.0F); + + for (int idx = 0; idx < 10; idx++) { + if (counter + idx >= this.materialStacks.length) { + break; + } + renderItemStackIntoPage( + materialStacks[counter + idx], + startX + (this.side == 0 ? 5 : (PAGECONTENTWIDTH - 21)), + startY + 2 + idx * 16, + scale); + } + + afterRenderItem(1.0F); + + // update displayed item + if (this.materialStacks.length > 10 && System.currentTimeMillis() - lastUpdate > 1000) { + lastUpdate = System.currentTimeMillis(); + counter += 10; + if (counter >= this.materialStacks.length) counter = 0; + } + } + + private void addNewTooltipsString(String str, int stringStartX, int stringStartY, float width, int height) { + addNewTooltipsString(str, stringStartX, stringStartY, (int) width, height); + } + + private void addNewTooltipsString(String str, int stringStartX, int stringStartY, int width, int height) { + widgetsList.add(new StringWithPosition(str, (int) (stringStartX), (int) (stringStartY), (int) (width), height)); + } +} diff --git a/src/main/java/tconstruct/client/pages/TiCPicturePage.java b/src/main/java/tconstruct/client/pages/TiCPicturePage.java new file mode 100644 index 00000000000..77515bd94c2 --- /dev/null +++ b/src/main/java/tconstruct/client/pages/TiCPicturePage.java @@ -0,0 +1,55 @@ +package tconstruct.client.pages; + +import static mantle.lib.CoreRepo.logger; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import mantle.client.pages.BookPage; + +public class TiCPicturePage extends BookPage { + + String text; + String location; + ResourceLocation background; + + @Override + public void readPageFromXML(Element element) { + NodeList nodes = element.getElementsByTagName("text"); + if (nodes != null) text = nodes.item(0).getTextContent(); + if (StatCollector.canTranslate(this.text)) this.text = StatCollector.translateToLocal(this.text); + + nodes = element.getElementsByTagName("location"); + if (nodes != null) { + location = nodes.item(0).getTextContent(); + background = new ResourceLocation(location); + if (background == null) { + logger.warn(nodes.item(0).getTextContent() + " could not be found in the image cache(location)!"); + } + } + + } + + @Override + public void renderContentLayer(int localWidth, int localHeight, boolean isTranslatable) { + manual.fonts.drawSplitString(text, localWidth + 8, localHeight + 6, 178, 0); + } + + public void renderBackgroundLayer(int localWidth, int localHeight) { + if (background != null) { + manual.getMC().getTextureManager().bindTexture(background); + + manual.drawTexturedModalRect( + localWidth, + localHeight + (TiCBookPage.PAGECONTENTHEIGHT - 120) / 2, + 0, + 0, + 170, + 144); + } + } + +} diff --git a/src/main/java/tconstruct/client/pages/TiCTextPage.java b/src/main/java/tconstruct/client/pages/TiCTextPage.java new file mode 100644 index 00000000000..ac299bd617e --- /dev/null +++ b/src/main/java/tconstruct/client/pages/TiCTextPage.java @@ -0,0 +1,26 @@ +package tconstruct.client.pages; + +import net.minecraft.util.StatCollector; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import mantle.client.pages.BookPage; + +public class TiCTextPage extends BookPage { + + String text; + + @Override + public void readPageFromXML(Element element) { + NodeList nodes = element.getElementsByTagName("text"); + if (nodes != null) text = nodes.item(0).getTextContent(); + if (StatCollector.canTranslate(text)) text = StatCollector.translateToLocal(text); + } + + @Override + public void renderContentLayer(int localWidth, int localHeight, boolean IsTranslatable) { + manual.fonts.drawSplitString(text, localWidth, localHeight, 178, 0); + } + +} diff --git a/src/main/java/tconstruct/library/TConstructRegistry.java b/src/main/java/tconstruct/library/TConstructRegistry.java index 493e692c787..ee3eee68fbb 100644 --- a/src/main/java/tconstruct/library/TConstructRegistry.java +++ b/src/main/java/tconstruct/library/TConstructRegistry.java @@ -380,7 +380,13 @@ public static ToolMaterial getMaterial(int key) { * @return Tool Material */ public static ToolMaterial getMaterial(String key) { - return (toolMaterialStrings.get(key)); + if (toolMaterialStrings.containsKey(key)) { + return (toolMaterialStrings.get(key)); + } + + // This is probably an old tool whose material has been removed from the game. + // Fall back to wood. + return toolMaterials.get(TinkerTools.MaterialID.Wood); } // Bow materials diff --git a/src/main/java/tconstruct/library/client/TConstructClientRegistry.java b/src/main/java/tconstruct/library/client/TConstructClientRegistry.java index 90acbab48ab..57e9c2d5552 100644 --- a/src/main/java/tconstruct/library/client/TConstructClientRegistry.java +++ b/src/main/java/tconstruct/library/client/TConstructClientRegistry.java @@ -2,15 +2,25 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; import net.minecraft.init.Items; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.item.crafting.IRecipe; + +import com.google.common.collect.Maps; import mantle.lib.client.MantleClientRegistry; import tconstruct.library.TConstructRegistry; import tconstruct.library.crafting.ModifyBuilder; import tconstruct.library.tools.ToolCore; +import tconstruct.util.TiCRecipeHolder; +import tconstruct.util.TiCRecipeHolder.RecipeType; public class TConstructClientRegistry { @@ -18,7 +28,8 @@ public class TConstructClientRegistry { public static ArrayList stencilButtons2 = new ArrayList<>(); public static ArrayList toolButtons = new ArrayList<>(20); public static ArrayList tierTwoButtons = new ArrayList<>(); - public static Map manualIcons = new HashMap<>(); + public static Map manualIcons = new HashMap<>(); + public static Map recipeIcons = Maps.newHashMap(); public static ItemStack defaultStack = new ItemStack(Items.iron_ingot); public static void addMaterialRenderMapping(int materialID, String domain, String renderName, @@ -113,6 +124,71 @@ public static void registerManualSmeltery(String name, ItemStack output, ItemSta MantleClientRegistry.recipeIcons.put(name, recipe); } + public static boolean checkHadManualIconRegistered(String name) { + return manualIcons.containsKey(name); + } + + public static void registerManualIcon(String name, ItemStack stack) { + manualIcons.put(name, stack); + } + + public static void registerManualIcon(String name, ItemStack[] stacks) { + if (!manualIcons.containsKey(name)) { + manualIcons.put(name, stacks); + } + } + + public static Object getManualIcon(String name) { + return manualIcons.get(name); + } + + public static ItemStack getOrRegisterManualIcon(String name) { + if (!checkHadManualIconRegistered(name)) { + String[] icon = name.split(":"); + String iconStackName = name; + int iconDamage = 0; + if (icon.length == 3) { + iconStackName = icon[0] + ":" + icon[1]; + iconDamage = Integer.parseInt(icon[2]); + } + ItemStack tempStack = new ItemStack((Item) Item.itemRegistry.getObject(iconStackName), 1, iconDamage); + registerManualIcon(name, tempStack); + } + return (ItemStack) getManualIcon(name); + } + + public static ItemStack getOrRegisterManualIcon(String name, ItemStack stack) { + if (!checkHadManualIconRegistered(name)) { + registerManualIcon(name, stack); + } + return (ItemStack) getManualIcon(name); + } + + public static TiCRecipeHolder[] getOrRegisterRecipeIcon(String name) { + if (!recipeIcons.containsKey(name)) { + ItemStack outPutStack = getOrRegisterManualIcon(name); + List recipes = new ArrayList<>(); + for (IRecipe i : CraftingManager.getInstance().getRecipeList()) { + ItemStack output = i.getRecipeOutput(); + if (output != null && output.isItemEqual(outPutStack)) recipes.add(new TiCRecipeHolder(i)); + } + + for (Entry t : FurnaceRecipes.smelting().getSmeltingList().entrySet()) { + if (t.getValue().isItemEqual(outPutStack)) recipes.add(new TiCRecipeHolder(t.getKey(), t.getValue())); + } + + recipeIcons.put(name, recipes.toArray(new TiCRecipeHolder[] {})); + } + return recipeIcons.get(name); + } + + public static void registerTiCToolRecipeIcon(String name, ItemStack[][] inputs, ItemStack output, RecipeType type) { + if (!recipeIcons.containsKey(name)) { + getOrRegisterManualIcon(name, output); + recipeIcons.put(name, new TiCRecipeHolder[] { new TiCRecipeHolder(inputs, output, type) }); + } + } + // Gui public static void addStencilButton(StencilGuiElement element) { stencilButtons.add(element); diff --git a/src/main/java/tconstruct/library/crafting/ToolRecipe.java b/src/main/java/tconstruct/library/crafting/ToolRecipe.java index bbc5a897279..a4eb15c5ca7 100644 --- a/src/main/java/tconstruct/library/crafting/ToolRecipe.java +++ b/src/main/java/tconstruct/library/crafting/ToolRecipe.java @@ -97,4 +97,24 @@ public boolean validExtra(Item input) { public ToolCore getType() { return result; } + + public LinkedList getHeadList() { + return headList; + } + + public LinkedList getHandleList() { + return handleList; + } + + public LinkedList getAccessoryList() { + return accessoryList; + } + + public LinkedList getExtraList() { + return extraList; + } + + public Item getToolRod() { + return toolRod; + } } diff --git a/src/main/java/tconstruct/library/modifier/ItemModifier.java b/src/main/java/tconstruct/library/modifier/ItemModifier.java index d3253e2c4b0..9dd5de72a41 100644 --- a/src/main/java/tconstruct/library/modifier/ItemModifier.java +++ b/src/main/java/tconstruct/library/modifier/ItemModifier.java @@ -15,6 +15,8 @@ public abstract class ItemModifier { public final List stacks; public final int effectIndex; public static Random random = new Random(); + public String tooltipName; + public String color; /** * Default constructor diff --git a/src/main/java/tconstruct/library/tools/ToolCore.java b/src/main/java/tconstruct/library/tools/ToolCore.java index e1836da0027..ad516f5145a 100644 --- a/src/main/java/tconstruct/library/tools/ToolCore.java +++ b/src/main/java/tconstruct/library/tools/ToolCore.java @@ -31,6 +31,7 @@ import tconstruct.library.modifier.IModifyable; import tconstruct.library.modifier.ItemModifier; import tconstruct.library.util.TextureHelper; +import tconstruct.modifiers.tools.ModReinforced; import tconstruct.tools.TinkerTools; import tconstruct.tools.entity.FancyEntityItem; import tconstruct.util.config.PHConstruct; @@ -362,28 +363,23 @@ public String getReinforcedName(int head, int handle, int accessory, int extra, tconstruct.library.tools.ToolMaterial extraMat = TConstructRegistry.getMaterial(extra); int reinforced = 0; - String style = ""; int current = headMat.reinforced(); if (current > 0) { - style = headMat.style(); reinforced = current; } current = handleMat.reinforced(); if (current > 0 && current > reinforced) { - style = handleMat.style(); reinforced = current; } if (getPartAmount() >= 3) { current = accessoryMat.reinforced(); if (current > 0 && current > reinforced) { - style = accessoryMat.style(); reinforced = current; } } if (getPartAmount() >= 4) { current = extraMat.reinforced(); if (current > 0 && current > reinforced) { - style = extraMat.style(); reinforced = current; } } @@ -391,27 +387,11 @@ public String getReinforcedName(int head, int handle, int accessory, int extra, reinforced += unbreaking - reinforced; if (reinforced > 0) { - return style + getReinforcedString(reinforced); + return "\u00a75" + ModReinforced.getReinforcedString(reinforced); } return ""; } - String getReinforcedString(int reinforced) { - if (reinforced > 9) return StatCollector.translateToLocal("tool.unbreakable"); - return StatCollector.translateToLocal("tool.reinforced") + " " + switch (reinforced) { - case 1 -> "I"; - case 2 -> "II"; - case 3 -> "III"; - case 4 -> "IV"; - case 5 -> "V"; - case 6 -> "VI"; - case 7 -> "VII"; - case 8 -> "VIII"; - case 9 -> "IX"; - default -> "X"; - }; - } - // Used for sounds and the like public void onEntityDamaged(World world, EntityLivingBase player, Entity entity) {} diff --git a/src/main/java/tconstruct/library/tools/ToolMaterial.java b/src/main/java/tconstruct/library/tools/ToolMaterial.java index 78ac689bfd2..5eeffb8fcf9 100644 --- a/src/main/java/tconstruct/library/tools/ToolMaterial.java +++ b/src/main/java/tconstruct/library/tools/ToolMaterial.java @@ -139,4 +139,10 @@ public String ability() { return StatCollector.translateToLocal(String.format("%s.ability", localizationString)); return ""; } + + public String abilityDesc() { + if (StatCollector.canTranslate(String.format("%s.ability.desc", localizationString))) + return StatCollector.translateToLocal(String.format("%s.ability.desc", localizationString)); + return ""; + } } diff --git a/src/main/java/tconstruct/library/util/ItemStackWithPosition.java b/src/main/java/tconstruct/library/util/ItemStackWithPosition.java new file mode 100644 index 00000000000..0648927d8c7 --- /dev/null +++ b/src/main/java/tconstruct/library/util/ItemStackWithPosition.java @@ -0,0 +1,55 @@ +package tconstruct.library.util; + +import java.util.List; + +import net.minecraft.item.ItemStack; + +public class ItemStackWithPosition implements WidgetsHasTooltips { + + final private ItemStack i; + + final private int startPositionX; + final private int startPositionY; + final private int width; + final private int height; + + final static int defaultWidth = 16; + final static int defaultHeight = 16; + + public ItemStackWithPosition(ItemStack i, int startPositionX, int startPositionY, int width, int height) { + this.i = i; + this.startPositionX = startPositionX; + this.startPositionY = startPositionY; + this.width = width; + this.height = height; + } + + public ItemStackWithPosition(ItemStack i, int startPositionX, int startPositionY, float scale) { + this.i = i; + this.startPositionX = (int) (startPositionX * scale); + this.startPositionY = (int) (startPositionY * scale); + this.width = (int) (defaultWidth * scale); + this.height = (int) (defaultHeight * scale); + } + + @Override + public boolean isHover(int mouseX, int mouseY) { + return (this.startPositionX <= mouseX && mouseX <= this.startPositionX + this.width) + && (this.startPositionY <= mouseY && mouseY <= this.startPositionY + this.height); + } + + public ItemStack getItemStack() { + return this.i; + } + + @Override + public List getTooltips() { + return null; + } + + @Override + public boolean needRenderTips() { + return true; + } + +} diff --git a/src/main/java/tconstruct/library/util/StringWithPosition.java b/src/main/java/tconstruct/library/util/StringWithPosition.java new file mode 100644 index 00000000000..a35553796be --- /dev/null +++ b/src/main/java/tconstruct/library/util/StringWithPosition.java @@ -0,0 +1,43 @@ +package tconstruct.library.util; + +import java.util.Arrays; +import java.util.List; + +public class StringWithPosition implements WidgetsHasTooltips { + + final private List tooltips; + + final private int startPositionX; + final private int startPositionY; + final private int width; + final private int height; + + public StringWithPosition(String tooltips, int startPositionX, int startPositionY, int width, int height) { + this(Arrays.asList(tooltips.split("\\\\n")), startPositionX, startPositionY, width, height, 1); + } + + public StringWithPosition(List tooltips, int startPositionX, int startPositionY, int width, int height, + float scale) { + this.tooltips = tooltips; + this.startPositionX = startPositionX; + this.startPositionY = startPositionY; + this.width = width; + this.height = height; + } + + public boolean isHover(int mouseX, int mouseY) { + return (this.startPositionX <= mouseX && mouseX <= this.startPositionX + this.width) + && (this.startPositionY <= mouseY && mouseY <= this.startPositionY + this.height); + } + + @Override + public List getTooltips() { + return this.tooltips; + } + + @Override + public boolean needRenderTips() { + return true; + } + +} diff --git a/src/main/java/tconstruct/library/util/TiCBookData.java b/src/main/java/tconstruct/library/util/TiCBookData.java new file mode 100644 index 00000000000..e6d09aebf03 --- /dev/null +++ b/src/main/java/tconstruct/library/util/TiCBookData.java @@ -0,0 +1,478 @@ +package tconstruct.library.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import mantle.books.BookData; +import tconstruct.TConstruct; +import tconstruct.items.tools.Cutlass; +import tconstruct.library.TConstructRegistry; +import tconstruct.library.client.TConstructClientRegistry; +import tconstruct.library.crafting.CastingRecipe; +import tconstruct.library.crafting.ModifyBuilder; +import tconstruct.library.crafting.PatternBuilder; +import tconstruct.library.crafting.PatternBuilder.ItemKey; +import tconstruct.library.crafting.PatternBuilder.MaterialSet; +import tconstruct.library.crafting.ToolBuilder; +import tconstruct.library.crafting.ToolRecipe; +import tconstruct.library.modifier.ItemModifier; +import tconstruct.library.tools.DualMaterialToolPart; +import tconstruct.library.tools.ToolMaterial; +import tconstruct.library.weaponry.AmmoItem; +import tconstruct.tools.TinkerTools; +import tconstruct.tools.items.ToolShard; +import tconstruct.util.TiCRecipeHolder.RecipeType; +import tconstruct.util.config.PHConstruct; +import tconstruct.weaponry.ammo.ArrowAmmo; +import tconstruct.weaponry.ammo.BoltAmmo; +import tconstruct.weaponry.weapons.Crossbow; + +public class TiCBookData extends BookData { + + private static final String ToolPagesButtonTag = "tictoolbuttons"; + private static final String MaterialsPagesButtonTag = "ticmaterialsbuttons"; + private static final String ModifiesPagesButtonTag = "ticmodifiesbuttons"; + + public boolean isInit = false; + + private final Map> replaceMap = new HashMap<>(); + + private Map indexMap = new HashMap<>(); + + private int bookColor = 0X8D754E; + + public int getBookColor() { + return bookColor; + } + + public TiCBookData setBookColor(int bookColor) { + this.bookColor = bookColor; + return this; + } + + public TiCBookData setUnlocalizedName(String unlocalizedName) { + this.unlocalizedName = unlocalizedName; + return this; + } + + public TiCBookData setToolTip(String toolTip) { + this.toolTip = toolTip; + return this; + } + + public TiCBookData setModID(String modID) { + this.modID = modID; + return this; + } + + public TiCBookData setItemImage(ResourceLocation itemImage) { + this.itemImage = itemImage; + return this; + } + + public TiCBookData setDoc(Document doc) { + this.doc = doc; + return this; + } + + @Override + public Document getDoc() { + this.isInit = false; + if (!this.isInit) { + this.isInit = true; + this.processGenerate(); + this.setupIndexAndMakeSureIsOdd(); + } + return this.doc; + } + + private void setupIndexAndMakeSureIsOdd() { + if (this.doc != null) { + NodeList pages = this.doc.getElementsByTagName("page"); + int pagesSize = pages.getLength(); + String pageName; + for (int idx = 0; idx < pagesSize; idx++) { + Element e = (Element) pages.item(idx); + if ((pageName = e.getAttribute("name")).length() != 0 && !this.indexMap.containsKey(pageName)) { + this.indexMap.put(pageName, idx); + } + } + if (pagesSize % 2 == 1) { + this.doc.getDocumentElement().appendChild(this.doc.createElement("page")); + } + } + } + + public int getIndexFromName(String name) { + if (this.indexMap.containsKey(name)) { + return this.indexMap.get(name); + } else { + return -1; + } + } + + private void replaceElementWithMultiple(Element target, List newElements) { + Node parent = target.getParentNode(); + Node nextSibling = target.getNextSibling(); + + parent.removeChild(target); + + while (nextSibling != null && nextSibling.getNodeType() != Node.ELEMENT_NODE) { + nextSibling = nextSibling.getNextSibling(); + } + + for (int i = 0; i < newElements.size(); i++) { + parent.insertBefore(newElements.get(i), nextSibling); + } + } + + private void processGenerate() { + this.replaceMap.clear(); + if (this.doc != null) { + NodeList pages = this.doc.getElementsByTagName("page"); + int pagesSize = pages.getLength(); + for (int idx = 0; idx < pagesSize; idx++) { + Element e = (Element) pages.item(idx); + if (e.getAttribute("type").equals(ToolPagesButtonTag)) { + replaceMap.put(e, generateTools(e)); + } else if (e.getAttribute("type").equals(MaterialsPagesButtonTag)) { + replaceMap.put(e, generateMaterials(e)); + } else if (e.getAttribute("type").equals(ModifiesPagesButtonTag)) { + replaceMap.put(e, generateModifes(e)); + } + } + replaceMap.entrySet().forEach((e) -> replaceElementWithMultiple(e.getKey(), e.getValue())); + } + } + + private List generateTools(Element parent) { + List navigationPages = new ArrayList<>(); + List newPages = new ArrayList<>(); + parent.setAttribute("type", "navigation"); + + String sizeStr = parent.getAttribute("capacity"); + int size = 5 * 5; + int counter = 0; + if (sizeStr.length() != 0) { + size = Integer.parseInt(sizeStr); + size *= size; + } + + Element target = (Element) parent.cloneNode(false); + + for (ToolRecipe r : ToolBuilder.instance.combos) { + // hide cutless as default + if (r.getType() instanceof Cutlass) { + continue; + } + + ItemStack head = r.getHeadList().size() != 0 + ? new ItemStack(r.getHeadList().getFirst(), 1, TinkerTools.MaterialID.Cobalt) + : null; + + ItemStack handle = r.getHandleList().size() != 0 + ? new ItemStack(r.getHandleList().getFirst(), 1, TinkerTools.MaterialID.Wood) + : null; + + ItemStack accessory = r.getAccessoryList().size() != 0 + ? new ItemStack(r.getAccessoryList().getFirst(), 1, TinkerTools.MaterialID.Iron) + : null; + + ItemStack extra = r.getExtraList().size() != 0 + ? new ItemStack(r.getExtraList().getFirst(), 1, TinkerTools.MaterialID.Ardite) + : null; + + if (r.getType() instanceof BoltAmmo) { + head = new ItemStack(r.getHeadList().getFirst(), 1, TinkerTools.MaterialID.Iron); + accessory = new ItemStack(r.getAccessoryList().getFirst(), 1, 0); + } else if (r.getType() instanceof Crossbow) { + accessory = new ItemStack(r.getAccessoryList().getFirst(), 1, 0); + } + + ItemStack output = ToolBuilder.instance + .buildTool(head, handle, accessory, extra, r.getType().getLocalizedToolName()); + + if (output != null) { + output.getTagCompound().getCompoundTag("InfiTool").setBoolean("Built", true); + if (r.getType() instanceof ArrowAmmo) { + // special display for arrow ammo + handle = new ItemStack(TinkerTools.toolRod, 1, TinkerTools.MaterialID.Wood); + } else if (r.getType() instanceof BoltAmmo) { + // special display for bolt ammo + head = DualMaterialToolPart.createDualMaterial( + r.getHeadList().getFirst(), + TinkerTools.MaterialID.Wood, + TinkerTools.MaterialID.Iron); + handle = null; + } + + if (r.getType() instanceof AmmoItem ai) { + ai.setAmmo(ai.getMaxAmmo(output), output); + } + + String toolUnlocalizedName = r.getType().getUnlocalizedToolName(); + + TConstructClientRegistry.registerTiCToolRecipeIcon( + toolUnlocalizedName, + new ItemStack[][] { new ItemStack[] { head }, new ItemStack[] { accessory }, + new ItemStack[] { handle }, new ItemStack[] { extra } }, + output, + extra != null ? RecipeType.ToolForge : RecipeType.ToolStation); + + Element newB = this.doc.createElement("button"); + newB.setAttribute("to", toolUnlocalizedName); + + Element itemStack = this.doc.createElement("icon"); + itemStack.setTextContent(toolUnlocalizedName); + + Element desc = this.doc.createElement("text"); + desc.setTextContent(output.getDisplayName()); + + newB.appendChild(itemStack); + newB.appendChild(desc); + target.appendChild(newB); + + counter++; + if (counter >= size) { + navigationPages.add(target); + target = (Element) parent.cloneNode(false); + counter = 0; + } + + Element newP = this.doc.createElement("page"); + newP.setAttribute("type", "ticcrafting"); + newP.setAttribute("name", toolUnlocalizedName); + + itemStack = this.doc.createElement("icon"); + itemStack.setTextContent(toolUnlocalizedName); + newP.appendChild(itemStack); + newPages.add(newP); + } + + } + if (counter != 0) { + navigationPages.add(target); + } + + navigationPages.addAll(newPages); + + return navigationPages; + } + + private List generateMaterials(Element parent) { + + Set materialNames = new HashSet(); + + List navigationPages = new ArrayList<>(); + List newPages = new ArrayList<>(); + parent.setAttribute("type", "navigation"); + Element target = (Element) parent.cloneNode(false); + + String sizeStr = parent.getAttribute("capacity"); + int size = 5 * 5; + int counter = 0; + if (sizeStr.length() != 0) { + size = Integer.parseInt(sizeStr); + size *= size; + } + + String formatedName; + ToolMaterial material; + for (int matID : TConstructRegistry.toolMaterials.keySet()) { + List toolParts = new ArrayList<>(); + + material = TConstructRegistry.toolMaterials.get(matID); + + if (material == null) { + TConstruct.logger.error(matID + " is null"); + continue; + } + + if (materialNames.contains(material.materialName)) { + continue; + } else { + materialNames.add(material.materialName); + } + + for (ItemKey key : PatternBuilder.instance.materials) { + MaterialSet set = PatternBuilder.instance.materialSets.get(key.key); + if (set.materialID == matID) { + toolParts.add(new ItemStack(key.item, 1, key.damage)); + } + } + + for (List list : TConstructRegistry.patternPartMapping.keySet()) { + if ((Integer) list.get(2) == matID) { + toolParts.add(TConstructRegistry.patternPartMapping.get(list)); + } + } + + if (!PHConstruct.craftMetalTools) { + for (CastingRecipe recipe : TConstructRegistry.getTableCasting().getCastingRecipes()) { + ItemStack castResult = recipe.getResult(); + if (castResult.getItem() instanceof IToolPart) { + if (((IToolPart) castResult.getItem()).getMaterialID(castResult) == matID) { + toolParts.add(castResult); + } + } + } + } + + Map seen = new HashMap<>(); + // TODO how to change to ItemStack.areItemStacksEqual? + List newToolParts = toolParts.stream().filter( + i -> (!(i.getItem() instanceof ToolShard || i.getItem().delegate.name().endsWith("ToolPartChunk")))) + .filter(p -> { + String k = p.getItem() + "@" + p.getItemDamage(); + if (seen.containsKey(k)) { + return false; + } else { + seen.put(k, p); + return true; + } + }).collect(Collectors.toList()); + + if (newToolParts.size() == 0 && toolParts.size() != 0) { + newToolParts.add(toolParts.get(0)); + } + + toolParts = newToolParts; + + formatedName = "material_" + material.materialName; + ItemStack[] iconStack = toolParts.toArray(new ItemStack[0]); + TConstructClientRegistry.registerManualIcon(formatedName, iconStack); + + Element newB = this.doc.createElement("button"); + newB.setAttribute("to", formatedName); + newB.setAttribute("color", String.valueOf(material.primaryColor())); + + Element icons = this.doc.createElement("icon"); + icons.setTextContent(formatedName); + + Element desc = this.doc.createElement("text"); + desc.setTextContent(material.style() + material.prefixName()); + + newB.appendChild(icons); + newB.appendChild(desc); + target.appendChild(newB); + + Element newP = this.doc.createElement("page"); + newP.setAttribute("type", "ticmaterial"); + newP.setAttribute("name", formatedName); + + Element materialName = this.doc.createElement("text"); + materialName.setTextContent(material.materialName); + newP.appendChild(materialName); + + materialName = this.doc.createElement("text"); + materialName.setTextContent(String.valueOf(matID)); + newP.appendChild(materialName); + + newPages.add(newP); + + counter++; + if (counter >= size) { + navigationPages.add(target); + target = (Element) parent.cloneNode(false); + counter = 0; + } + + } + + if (counter != 0) { + navigationPages.add(target); + } + + navigationPages.addAll(newPages); + + return navigationPages; + } + + private List generateModifes(Element parent) { + List navigationPages = new ArrayList<>(); + List newPages = new ArrayList<>(); + parent.setAttribute("type", "navigation"); + + String sizeStr = parent.getAttribute("capacity"); + int size = 5 * 5; + int counter = 0; + if (sizeStr.length() != 0) { + size = Integer.parseInt(sizeStr); + size *= size; + } + + Element target = (Element) parent.cloneNode(false); + + for (ItemModifier im : ModifyBuilder.instance.itemModifiers) { + + if (im.tooltipName != null) { + String locString = "modifier.tooltip." + + EnumChatFormatting.getTextWithoutFormattingCodes(im.tooltipName).replace(" ", ""); + TConstruct.logger.info( + im.effectIndex + ": " + + im.key + + "=================================================" + + StatCollector.translateToLocal(locString)); + } else { + TConstruct.logger + .info(im.effectIndex + ": " + im.key + "================================================="); + } + List collect = im.stacks.stream().map(ItemStack::getDisplayName).collect(Collectors.toList()); + TConstruct.logger.info(Arrays.toString(collect.toArray(new String[0]))); + + // Element newB = this.doc.createElement("button"); + // newB.setAttribute("to", toolUnlocalizedName); + // + // Element itemStack = this.doc.createElement("icon"); + // itemStack.setTextContent(toolUnlocalizedName); + // + // Element desc = this.doc.createElement("text"); + // desc.setTextContent(output.getDisplayName()); + // + // newB.appendChild(itemStack); + // newB.appendChild(desc); + // target.appendChild(newB); + // + // counter++; + // if (counter >= size) { + // navigationPages.add(target); + // target = (Element) parent.cloneNode(false); + // counter = 0; + // } + // + // Element newP = this.doc.createElement("page"); + // newP.setAttribute("type", "ticcrafting"); + // newP.setAttribute("name", toolUnlocalizedName); + // + // itemStack = this.doc.createElement("icon"); + // itemStack.setTextContent(toolUnlocalizedName); + // newP.appendChild(itemStack); + // newPages.add(newP); + + } + // if (counter != 0) { + // navigationPages.add(target); + // } + + navigationPages.addAll(newPages); + + return navigationPages; + } + +} diff --git a/src/main/java/tconstruct/library/util/TiCGuiButton.java b/src/main/java/tconstruct/library/util/TiCGuiButton.java new file mode 100644 index 00000000000..f7bede49d09 --- /dev/null +++ b/src/main/java/tconstruct/library/util/TiCGuiButton.java @@ -0,0 +1,38 @@ +package tconstruct.library.util; + +import java.util.List; + +import net.minecraft.client.gui.GuiButton; + +import tconstruct.client.pages.TiCBookPage; + +public abstract class TiCGuiButton extends GuiButton implements WidgetsHasTooltips { + + public TiCBookPage parentPage; + public List toolTips; + public boolean needRenderTips = true; + + public TiCGuiButton(int stateName, int id, int p_i1021_3_, int p_i1021_4_, int p_i1021_5_, String p_i1021_6_, + TiCBookPage parentPage) { + super(stateName, id, p_i1021_3_, p_i1021_4_, p_i1021_5_, p_i1021_6_); + this.parentPage = parentPage; + } + + @Override + public boolean isHover(int mouseX, int mouseY) { + return mouseX >= this.xPosition && mouseY >= this.yPosition + && mouseX < this.xPosition + this.width + && mouseY < this.yPosition + this.height; + } + + @Override + public List getTooltips() { + return this.toolTips; + } + + @Override + public boolean needRenderTips() { + return this.needRenderTips; + } + +} diff --git a/src/main/java/tconstruct/library/util/TiCGuiManual.java b/src/main/java/tconstruct/library/util/TiCGuiManual.java new file mode 100644 index 00000000000..458799f2f5c --- /dev/null +++ b/src/main/java/tconstruct/library/util/TiCGuiManual.java @@ -0,0 +1,428 @@ +package tconstruct.library.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import mantle.books.BookData; +import mantle.client.MProxyClient; +import mantle.client.RenderItemCopy; +import mantle.client.SmallFontRenderer; +import mantle.client.gui.GuiManual; +import mantle.client.pages.BookPage; +import tconstruct.TConstruct; +import tconstruct.client.pages.TiCBookPage; +import tconstruct.library.util.TiCTurnPageButton.ButtonType; + +@SideOnly(Side.CLIENT) +public class TiCGuiManual extends GuiManual { + + private static final int ANIMATIONDURATIONINMILLIS = 600; + private static final float FLYIN_DURATION = 0.55f; // portion for fly-in + private static final float OVERSHOOT_DURATION = 0.1f; // portion for overshoot + private static final float EXTENT = 0.02f; // overshoot amount as fraction of total displacement + private static final float GUIMAXPERCENTAGE = 0.85f; // The maximum percentage that the manual GUI can occupy + + ItemStack itemstackBook; + Document manual; + public RenderItemCopy renderitem = new RenderItemCopy(); + final static int BOOKIMAGEWIDTH = 206; + final static int BOOKIMAGEHEIGHT = 200; + int bookTotalPages = 1; + int jumpFromPage = -1; + int currentPage; + int maxPages; + BookData bData; + + private TiCTurnPageButton buttonNextPage; + private TiCTurnPageButton buttonPreviousPage; + private TiCTurnPageButton buttonHomePage; + private TiCTurnPageButton buttonBackToJumpFrom; + + private static final ResourceLocation bookRightBackGround = new ResourceLocation( + "tinker", + "textures/gui/bookrightbackground.png"); + private static final ResourceLocation bookLeftBackGround = new ResourceLocation( + "tinker", + "textures/gui/bookleftbackground.png"); + private static final ResourceLocation bookRightPage = new ResourceLocation( + "tinker", + "textures/gui/bookrightpage.png"); + private static final ResourceLocation bookLeftPage = new ResourceLocation( + "tinker", + "textures/gui/bookleftpage.png"); + + private long guiOpenTime; + + public float scale = 1.0f; + private int baseDrawingX; + private int baseDrawingY; + BookPage pageLeft; + BookPage pageRight; + + public SmallFontRenderer fonts = MProxyClient.smallFontRenderer; + + public TiCGuiManual(ItemStack stack, BookData data) { + super(stack, data); + this.mc = Minecraft.getMinecraft(); + this.itemstackBook = stack; + currentPage = 0; // Stack page + manual = data.getDoc(); + if (data.font != null) this.fonts = data.font; + this.bData = data; + this.guiOpenTime = System.currentTimeMillis(); + + // renderitem.renderInFrame = true; + } + + /* + * @Override publi c void setWorldAndResolution (Minecraft minecraft, int w, int h) { this.guiParticles = new + * GuiParticle(minecraft); this.mc = minecraft; this.width = w; this.height = h; this.buttonList.clear(); + * this.initGui(); } + */ + + public void initGui() { + maxPages = manual.getElementsByTagName("page").getLength(); + ticUpdateText(); + this.buttonList.add(this.buttonNextPage = new TiCTurnPageButton(1, 0, 0, ButtonType.nextPage, null)); + this.buttonList.add(this.buttonPreviousPage = new TiCTurnPageButton(2, 0, 0, ButtonType.previousPage, null)); + this.buttonList.add(this.buttonHomePage = new TiCTurnPageButton(3, 0, 0, ButtonType.homePage, null)); + this.buttonList + .add(this.buttonBackToJumpFrom = new TiCTurnPageButton(4, 0, 0, ButtonType.backToJumpFrom, null)); + updateButtonVisibility(); + } + + private void updateButtonVisibility() { + buttonPreviousPage.visible = currentPage > 0; + buttonNextPage.visible = currentPage < maxPages - 2; + buttonHomePage.visible = currentPage != 0; + buttonBackToJumpFrom.visible = jumpFromPage != -1; + } + + protected void actionPerformed(GuiButton button) { + if (button.enabled) { + if (button instanceof TiCGuiButton tgb) { + if (tgb.parentPage != null) { + tgb.parentPage.actionPerformed(button, this.bData); + } else { + changePage(button.id); + } + } + } + } + + @Override + protected void keyTyped(char typedChar, int keyCode) { + // right arrow is 205 + // left arrow is 203 + if (keyCode == 205) { + this.turnToNextPage(); + } else if (keyCode == 203) { + this.turnToPreviousPage(); + } else { + super.keyTyped(typedChar, keyCode); + } + } + + void ticUpdateText() { + if (maxPages % 2 == 1) { + if (currentPage > maxPages) currentPage = maxPages; + } else { + if (currentPage >= maxPages) currentPage = maxPages - 2; + } + if (currentPage % 2 == 1) currentPage--; + if (currentPage < 0) currentPage = 0; + + NodeList nList = manual.getElementsByTagName("page"); + + Node node = nList.item(currentPage); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) node; + Class clazz = MProxyClient.getPageClass(element.getAttribute("type")); + if (clazz != null) { + try { + pageLeft = clazz.getDeclaredConstructor().newInstance(); + pageLeft.init(this, 0); + pageLeft.readPageFromXML(element); + } catch (Exception e) { + TConstruct.logger.error(e); + } + } else { + pageLeft = null; + } + } + + node = nList.item(currentPage + 1); + if (node != null && node.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) node; + Class clazz = MProxyClient.getPageClass(element.getAttribute("type")); + if (clazz != null) { + try { + pageRight = clazz.getDeclaredConstructor().newInstance(); + pageRight.init(this, 1); + pageRight.readPageFromXML(element); + } catch (Exception e) { + TConstruct.logger.error(e); + } + } else { + pageRight = null; + } + } + } + + @Override + public void handleMouseInput() { + int scrollAmount = Mouse.getEventDWheel(); + + if (scrollAmount > 0 && currentPage > 0) { + this.turnToPreviousPage(); + } else if (scrollAmount < 0 && currentPage + 2 < maxPages) { + this.turnToNextPage(); + } else { + super.handleMouseInput(); + } + } + + private void changePage(int buttonId) { + if (buttonId == 1) { + this.turnToNextPage(); + } + if (buttonId == 2) { + this.turnToPreviousPage(); + } + if (buttonId == 3) { + this.setCurrentPage(0); + } + if (buttonId == 4) { + this.setCurrentPage(this.jumpFromPage); + } + } + + public void turnToNextPage() { + this.setCurrentPage(this.currentPage + 2); + } + + public void turnToPreviousPage() { + this.setCurrentPage(this.currentPage - 2); + } + + public void setCurrentPage(int pageNum) { + if (Math.abs(pageNum - this.currentPage) > 2 && pageNum != this.jumpFromPage) { + this.jumpFromPage = this.currentPage; + } else { + this.jumpFromPage = -1; + } + + this.currentPage = Math.min(Math.max(pageNum, 0), maxPages); + updateButtonVisibility(); + ticUpdateText(); + } + + public void drawScreen(int par1, int par2, float par3) { + this.buttonList.subList(4, this.buttonList.size()).clear(); + + this.scale = Math.max( + 0.99f, + Math.min( + this.width * GUIMAXPERCENTAGE / (BOOKIMAGEWIDTH * 2), + this.height * GUIMAXPERCENTAGE / BOOKIMAGEHEIGHT)); + + float progress = (System.currentTimeMillis() - this.guiOpenTime) * 1.0f / ANIMATIONDURATIONINMILLIS; + + int[] point = this.getOvershootPosition(progress, scale); + this.baseDrawingX = point[0]; + this.baseDrawingY = point[1]; + + int drawX = (int) (this.baseDrawingX / scale); + int drawY = (int) (this.baseDrawingY / scale); + + GL11.glPushMatrix(); + GL11.glScalef(scale, scale, 1.0f); + + int backGroundColor = 0xD89A1D; + if (this.bData instanceof TiCBookData tbd) { + backGroundColor = tbd.getBookColor(); + } + + float r = ((backGroundColor >> 16) & 0xFF) / 255.0f; + float g = ((backGroundColor >> 8) & 0xFF) / 255.0f; + float b = (backGroundColor & 0xFF) / 255.0f; + + GL11.glColor4f(r, g, b, 1.0F); + this.mc.getTextureManager().bindTexture(bookRightBackGround); + this.drawTexturedModalRect(drawX, drawY, 0, 0, BOOKIMAGEWIDTH, BOOKIMAGEHEIGHT); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.getTextureManager().bindTexture(bookRightPage); + this.drawTexturedModalRect(drawX, drawY, 0, 0, BOOKIMAGEWIDTH, BOOKIMAGEHEIGHT); + + drawX = drawX - BOOKIMAGEWIDTH; + int textureX = 256 - BOOKIMAGEWIDTH; + GL11.glColor4f(r, g, b, 1.0F); + this.mc.getTextureManager().bindTexture(bookLeftBackGround); + this.drawTexturedModalRect(drawX, drawY, textureX, 0, BOOKIMAGEWIDTH, BOOKIMAGEHEIGHT); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.getTextureManager().bindTexture(bookLeftPage); + this.drawTexturedModalRect(drawX, drawY, textureX, 0, BOOKIMAGEWIDTH, BOOKIMAGEHEIGHT); + + this.drawButtons(par1, par2, scale); + + if (pageLeft != null) { + if (pageLeft instanceof TiCBookPage tbbp) { + tbbp.updateButtonPositionAndRender(drawX + 16, drawY + 12, scale, par1, par2, this.buttonList); + } else { + pageLeft.renderBackgroundLayer(drawX + 16, drawY + 12); + pageLeft.renderContentLayer(drawX + 16, drawY + 12, bData.isTranslatable); + } + // because of some mantel page will draw some string in content + // and it will set color to 0x000000, so reset it + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + if (pageRight != null) { + if (pageRight instanceof TiCBookPage tbbp) { + tbbp.updateButtonPositionAndRender( + drawX + BOOKIMAGEWIDTH + 5, + drawY + 12, + scale, + par1, + par2, + this.buttonList); + } else { + pageRight.renderBackgroundLayer(drawX + 220, drawY + 12); + pageRight.renderContentLayer(drawX + 220, drawY + 12, bData.isTranslatable); + } + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + GL11.glPopMatrix(); + this.renderButtonAndStackTooltips(par1, par2); + } + + void renderButtonAndStackTooltips(int mouseX, int mouseY) { + this.buttonList.forEach(b -> { + if (b instanceof WidgetsHasTooltips tgb && tgb.isHover(mouseX, mouseY) && tgb.needRenderTips()) { + this.drawHoveringText(tgb.getTooltips(), mouseX, mouseY, fontRendererObj); + } + }); + + if (pageLeft != null && pageLeft instanceof TiCBookPage tbbp) { + tbbp.widgetsList.forEach(t -> { + if (t.isHover(mouseX, mouseY)) { + if (t instanceof ItemStackWithPosition iswp) { + this.renderToolTip(iswp.getItemStack(), mouseX, mouseY); + } else if (t.needRenderTips()) { + this.drawHoveringText(t.getTooltips(), mouseX, mouseY, fontRendererObj); + } + } + }); + } + + if (pageRight != null && pageRight instanceof TiCBookPage tbbp) { + tbbp.widgetsList.forEach(t -> { + if (t.isHover(mouseX, mouseY)) { + if (t instanceof ItemStackWithPosition iswp) { + this.renderToolTip(iswp.getItemStack(), mouseX, mouseY); + } else if (t.needRenderTips()) { + this.drawHoveringText(t.getTooltips(), mouseX, mouseY, fontRendererObj); + } + } + }); + } + } + + /** + * copy from {@link net.minecraft.client.gui.GuiScreen#drawScreen(int, int, float)} + */ + public void drawButtons(int mouseX, int mouseY, float scale) { + + // base on `xPos + BOOKIMAGEWIDTH - 50`, (206 - 50) / 206 ≈ 0.757 and (206 - 24) + // / 206 ≈ 0.883 + this.buttonNextPage.xPosition = this.baseDrawingX + (int) (BOOKIMAGEWIDTH * scale * 0.8f); + this.buttonPreviousPage.xPosition = this.baseDrawingX - (int) (BOOKIMAGEWIDTH * scale * 0.883f); + this.buttonHomePage.xPosition = this.baseDrawingX + - (int) ((BOOKIMAGEWIDTH + TiCTurnPageButton.ButtonType.homePage.textureWidth * 0.75f) * scale); + this.buttonBackToJumpFrom.xPosition = this.baseDrawingX + - (int) (TiCTurnPageButton.ButtonType.backToJumpFrom.textureWidth * 0.5f * scale); + + // base on scale calculate the real y position of the bottom gui + // and base on `(this.height + this.bookImageHeight) / 2 - 28`, the default + // button height is 13 + // 28 / 13 ≈ 2.15, so keep the same ratio + int yPosition = this.baseDrawingY + + (int) ((BOOKIMAGEHEIGHT - TiCTurnPageButton.ButtonType.nextPage.textureHeight * 2.747f) * scale); + this.buttonNextPage.yPosition = yPosition; + this.buttonPreviousPage.yPosition = yPosition; + this.buttonHomePage.yPosition = this.baseDrawingY + + (int) (TiCTurnPageButton.ButtonType.homePage.textureHeight * 0.5f); + this.buttonBackToJumpFrom.yPosition = yPosition; + + this.buttonBackToJumpFrom.drawButtonWithScale(this.mc, mouseX, mouseY, scale); + this.buttonNextPage.drawButtonWithScale(this.mc, mouseX, mouseY, scale); + this.buttonPreviousPage.drawButtonWithScale(this.mc, mouseX, mouseY, scale); + this.buttonHomePage.drawButtonWithScale(this.mc, mouseX, mouseY, scale); + } + + public Minecraft getMC() { + return mc; + } + + public boolean doesGuiPauseGame() { + return false; + } + + /** + * Computes the current position after applying an overshoot and bounce animation. + * + * @param progress global animation progress in [0,1], where 0 = start, 1 = end + * @return the current (X, Y) point for the given progress + */ + private int[] getOvershootPosition(float progress, float scale) { + int endX = (this.width / 2); + int startX = endX; + + int endY = (int) ((this.height - BOOKIMAGEHEIGHT * scale) / 2); + int startY = (int) (this.height + BOOKIMAGEHEIGHT * scale); + + // Clamp progress to [0,1] + float t = Math.min(Math.max(progress, 0.0f), 1.0f); + + float factor; // displacement factor (0 → 1+EXTENT → 1) + + if (t <= FLYIN_DURATION) { + // Phase 1: linear fly in + float phaseT = t / FLYIN_DURATION; // [0,1] + factor = phaseT; + } else if (t <= FLYIN_DURATION + OVERSHOOT_DURATION) { + // Phase 2: overshoot (1 → 1+EXTENT) with ease out + float phaseT = (t - FLYIN_DURATION) / OVERSHOOT_DURATION; // [0,1] + float eased = (float) (1.0f - Math.pow(1.0f - phaseT, 2.0f)); + factor = 1.0f + EXTENT * eased; + } else { + // Phase 3: correct back to target (1+EXTENT → 1) linear + float remaining = 1.0f - (FLYIN_DURATION + OVERSHOOT_DURATION); + float phaseT = (t - (FLYIN_DURATION + OVERSHOOT_DURATION)) / remaining; // [0,1] + float peak = 1.0f + EXTENT; + factor = peak + (1.0f - peak) * phaseT; + } + + // Clamp factor to reasonable range (should stay inside [0, 1+EXTENT]) + factor = Math.min(factor, 1.0f + EXTENT); + + // Linear interpolation + int x = (int) (startX + (endX - startX) * factor); + int y = (int) (startY + (endY - startY) * factor); + + return new int[] { x, y }; + } + +} diff --git a/src/main/java/tconstruct/library/util/TiCNavigationButton.java b/src/main/java/tconstruct/library/util/TiCNavigationButton.java new file mode 100644 index 00000000000..fad55e8ae30 --- /dev/null +++ b/src/main/java/tconstruct/library/util/TiCNavigationButton.java @@ -0,0 +1,184 @@ +package tconstruct.library.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.item.ItemStack; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import mantle.client.SmallFontRenderer; +import tconstruct.client.pages.TiCBookPage; +import tconstruct.util.McTextFormatter; + +public class TiCNavigationButton extends TiCGuiButton { + + public enum ButtonSize { + + small(0.8f), + large(2f), + medium(1f); + + public float multi; + + ButtonSize(float multi) { + this.multi = multi; + } + + public static ButtonSize getSize(String s) { + switch (s) { + case "large": + return large; + case "small": + return small; + case "medium": + return medium; + default: + return large; + } + } + } + + public static final int defaultHeight = 20; + public static final int defaultWidth = 20; + + RenderItem itemRender = new RenderItem(); + ButtonSize bs; + public ItemStack[] renderStack; + public String target; + public String ButtonStr; + public int color; + + public long lastUpdate; + public int counter; + + public TiCNavigationButton(int id, ButtonSize bs, ItemStack s, String ButtonStr, String target, + TiCBookPage parentPage) { + this( + id, + bs, + new ItemStack[] { s }, + ButtonStr, + target, + ButtonStr.length() != 0 ? Arrays.asList(ButtonStr) : new ArrayList<>(), + parentPage, + 0x000000); + } + + public TiCNavigationButton(int id, ButtonSize bs, ItemStack[] s, String target, String tooltips, + TiCBookPage parentPage, int color) { + this(id, bs, s, "", target, Arrays.asList(tooltips), parentPage, color); + } + + public TiCNavigationButton(int id, ButtonSize bs, ItemStack[] s, String ButtonStr, String target, + List tooltips, TiCBookPage parentPage, int color) { + super(id, 0, 0, defaultHeight, defaultWidth, "", parentPage); + this.bs = bs; + this.renderStack = s; + this.ButtonStr = ButtonStr; + this.target = target; + this.toolTips = tooltips; + this.color = color; + + this.lastUpdate = System.currentTimeMillis(); + this.counter = 0; + } + + public void drawButtonWithScale(Minecraft mc, int mouseX, int mouseY, float scale, SmallFontRenderer fonts) { + if (this.visible) { + this.height = (int) (defaultHeight * this.bs.multi * scale); + this.width = (int) (defaultWidth * this.bs.multi * scale); + + boolean isMouseInButton = this.isHover(mouseX, mouseY); + + if (isMouseInButton) { + GuiButton.drawRect( + (int) (this.xPosition / scale), + (int) (this.yPosition / scale), + (int) ((this.xPosition / scale + defaultWidth * this.bs.multi)), + (int) ((this.yPosition / scale + defaultHeight * this.bs.multi)), + 0xAAAAAAAA); + } + + String boldButtonStr = McTextFormatter.addBold(this.ButtonStr); + + // let string a half size of multi + GL11.glScalef(this.bs.multi / 2, this.bs.multi / 2, 1.0f); + if (fonts.getStringWidth(boldButtonStr) <= this.width / scale / this.bs.multi * 2) { + fonts.drawString( + boldButtonStr, + (int) ((this.xPosition + this.width / 2) / scale / this.bs.multi * 2 + - fonts.getStringWidth(boldButtonStr) / 2), + (int) ((this.yPosition + this.height) / scale / this.bs.multi * 2 - fonts.FONT_HEIGHT), + this.color); + } else { + // much smaller + GL11.glScalef(0.8f, 0.8f, 1.0f); + fonts.drawString( + boldButtonStr, + (int) ((this.xPosition + this.width / 2) / scale / this.bs.multi * 2.5 + - fonts.getStringWidth(boldButtonStr) / 2), + (int) ((this.yPosition + this.height) / scale / this.bs.multi * 2.5 - fonts.FONT_HEIGHT), + this.color); + // resize back + GL11.glScalef(1.25f, 1.25f, 1.0f); + } + // resize back and reset color + GL11.glScalef(2.0f, 2.0f, 1.0f); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + this.drawItem(mc, scale); + GL11.glScalef(1.0f / this.bs.multi, 1.0f / this.bs.multi, 1.0f); + } + } + + private void drawItem(final Minecraft mc, float scale) { + int length = renderStack.length; + if (length == 0) { + return; + } + + if (length > 1 && System.currentTimeMillis() - lastUpdate > 1000) { + lastUpdate = System.currentTimeMillis(); + counter++; + if (counter >= length) counter = 0; + } + + GL11.glPushMatrix(); + RenderHelper.enableGUIStandardItemLighting(); + this.zLevel = 100.0F; + this.itemRender.zLevel = 100.0F; + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + this.itemRender.renderItemAndEffectIntoGUI( + mc.fontRenderer, + mc.renderEngine, + this.renderStack[this.counter % length], + (int) (this.xPosition / scale / this.bs.multi + 2), + (int) (this.yPosition / scale / this.bs.multi + (this.ButtonStr.length() == 0 ? 2 : 0))); + this.itemRender.renderItemOverlayIntoGUI( + mc.fontRenderer, + mc.renderEngine, + this.renderStack[this.counter % length], + (int) (this.xPosition / scale / this.bs.multi + 2), + (int) (this.yPosition / scale / this.bs.multi + (this.ButtonStr.length() == 0 ? 2 : 0))); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + this.itemRender.zLevel = 0.0F; + this.zLevel = 0.0F; + RenderHelper.disableStandardItemLighting(); + GL11.glPopMatrix(); + } + + @Override + public boolean needRenderTips() { + return this.needRenderTips; + } + +} diff --git a/src/main/java/tconstruct/library/util/TiCTurnPageButton.java b/src/main/java/tconstruct/library/util/TiCTurnPageButton.java new file mode 100644 index 00000000000..90659e766d1 --- /dev/null +++ b/src/main/java/tconstruct/library/util/TiCTurnPageButton.java @@ -0,0 +1,96 @@ +package tconstruct.library.util; + +import java.util.Arrays; +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; + +import org.lwjgl.opengl.GL11; + +import tconstruct.client.pages.TiCBookPage; + +public class TiCTurnPageButton extends TiCGuiButton { + + public enum ButtonType { + + nextPage(0, 16, 18, 10, "nextPage"), + previousPage(0, 26, 18, 10, "previousPage"), + backToJumpFrom(0, 36, 18, 10, "backToJumpFrom"), + homePage(0, 0, 14, 16, "homePage"); + + int textureX; + int textureY; + int textureWidth; + int textureHeight; + List tooltips; + + ButtonType(int textureX, int textureY, int textureWidth, int textureHeight, String tooltips) { + this.textureX = textureX; + this.textureY = textureY; + this.textureWidth = textureWidth; + this.textureHeight = textureHeight; + this.tooltips = Arrays + .asList(StatCollector.translateToLocal("tconstruct.manual.button.tooltip." + tooltips)); + } + + } + + public static int ARROWCOLOR = 0xFFFFD3; + public static int ARROWCOLORHOVER = 0xFF541C; + + private final ButtonType buttonType; + private static final ResourceLocation background = new ResourceLocation( + "tinker", + "textures/gui/bookleftbackground.png"); + + public TiCTurnPageButton(int id, int xPosition, int yPosition, ButtonType buttonType, TiCBookPage parentPage) { + super(id, xPosition, yPosition, buttonType.textureWidth, buttonType.textureHeight, "", parentPage); + this.buttonType = buttonType; + } + + public int getWidth() { + return this.buttonType.textureWidth; + } + + public int getHeight() { + return this.buttonType.textureHeight; + } + + public void drawButton(Minecraft mc, int mouseX, int mouseY) { + this.drawButtonWithScale(mc, mouseX, mouseY, 1.0f); + } + + public void drawButtonWithScale(Minecraft mc, int mouseX, int mouseY, float scale) { + if (this.visible) { + this.width = (int) (this.buttonType.textureWidth * scale); + this.height = (int) (this.buttonType.textureHeight * scale); + + boolean isMouseInButton = this.isHover(mouseX, mouseY); + + mc.getTextureManager().bindTexture(background); + + if (isMouseInButton) { + GL11.glColor4f(255f / 255, 84f / 255, 28f / 255, 1.0F); + } else { + GL11.glColor4f(255f / 255, 255f / 255, 221f / 255, 1.0F); + } + + this.drawTexturedModalRect( + (int) (this.xPosition / scale), + (int) (this.yPosition / scale), + this.buttonType.textureX, + this.buttonType.textureY, + this.buttonType.textureWidth, + this.buttonType.textureHeight); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + } + + @Override + public List getTooltips() { + return this.buttonType.tooltips; + } +} diff --git a/src/main/java/tconstruct/library/util/WidgetsHasTooltips.java b/src/main/java/tconstruct/library/util/WidgetsHasTooltips.java new file mode 100644 index 00000000000..dc0c53078e4 --- /dev/null +++ b/src/main/java/tconstruct/library/util/WidgetsHasTooltips.java @@ -0,0 +1,13 @@ +package tconstruct.library.util; + +import java.util.List; + +public interface WidgetsHasTooltips { + + public List getTooltips(); + + public boolean needRenderTips(); + + public boolean isHover(int mouseX, int mouseY); + +} diff --git a/src/main/java/tconstruct/modifiers/accessory/GloveSpeed.java b/src/main/java/tconstruct/modifiers/accessory/GloveSpeed.java index a9adf96bd44..f2a8a515016 100644 --- a/src/main/java/tconstruct/modifiers/accessory/GloveSpeed.java +++ b/src/main/java/tconstruct/modifiers/accessory/GloveSpeed.java @@ -12,7 +12,6 @@ public class GloveSpeed extends ItemModTypeFilter { - String tooltipName; int max = 100; public GloveSpeed(int effect, ItemStack[] items, int[] values) { diff --git a/src/main/java/tconstruct/modifiers/armor/AModBoolean.java b/src/main/java/tconstruct/modifiers/armor/AModBoolean.java index 5a3dee06b1c..08e1188d650 100644 --- a/src/main/java/tconstruct/modifiers/armor/AModBoolean.java +++ b/src/main/java/tconstruct/modifiers/armor/AModBoolean.java @@ -15,7 +15,6 @@ public class AModBoolean extends ArmorMod { String color; - String tooltipName; public AModBoolean(int effect, String tag, EnumSet armorTypes, ItemStack[] items, String c, String tip) { super(effect, tag, armorTypes, items); diff --git a/src/main/java/tconstruct/modifiers/armor/AModInteger.java b/src/main/java/tconstruct/modifiers/armor/AModInteger.java index dc209800417..3f325d870f5 100644 --- a/src/main/java/tconstruct/modifiers/armor/AModInteger.java +++ b/src/main/java/tconstruct/modifiers/armor/AModInteger.java @@ -13,7 +13,6 @@ public class AModInteger extends ArmorMod { String color; - String tooltipName; int initialIncrease; int secondaryIncrease; diff --git a/src/main/java/tconstruct/modifiers/tools/ModAntiSpider.java b/src/main/java/tconstruct/modifiers/tools/ModAntiSpider.java index 36f987b2b41..215b054f874 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModAntiSpider.java +++ b/src/main/java/tconstruct/modifiers/tools/ModAntiSpider.java @@ -5,7 +5,6 @@ public class ModAntiSpider extends ItemModTypeFilter { - String tooltipName; int max = 4; String guiType; diff --git a/src/main/java/tconstruct/modifiers/tools/ModAttack.java b/src/main/java/tconstruct/modifiers/tools/ModAttack.java index 657eec9f2e0..fc8881684e3 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModAttack.java +++ b/src/main/java/tconstruct/modifiers/tools/ModAttack.java @@ -10,7 +10,6 @@ public class ModAttack extends ItemModTypeFilter { - String tooltipName; int max; int threshold; String guiType; diff --git a/src/main/java/tconstruct/modifiers/tools/ModBlaze.java b/src/main/java/tconstruct/modifiers/tools/ModBlaze.java index ac4d588b9d2..38e3cd1ae4c 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModBlaze.java +++ b/src/main/java/tconstruct/modifiers/tools/ModBlaze.java @@ -10,7 +10,6 @@ public class ModBlaze extends ItemModTypeFilter { - String tooltipName; int max; public ModBlaze(int effect, ItemStack[] items, int[] values) { diff --git a/src/main/java/tconstruct/modifiers/tools/ModBoolean.java b/src/main/java/tconstruct/modifiers/tools/ModBoolean.java index c7717937e50..fcfdd553240 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModBoolean.java +++ b/src/main/java/tconstruct/modifiers/tools/ModBoolean.java @@ -10,7 +10,6 @@ public class ModBoolean extends ItemModifier { String color; - String tooltipName; public ModBoolean(ItemStack[] items, int effect, String tag, String c, String tip) { super(items, effect, tag); diff --git a/src/main/java/tconstruct/modifiers/tools/ModDurability.java b/src/main/java/tconstruct/modifiers/tools/ModDurability.java index a30952ddc7b..f5ca64fc435 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModDurability.java +++ b/src/main/java/tconstruct/modifiers/tools/ModDurability.java @@ -10,7 +10,6 @@ public class ModDurability extends ItemModifier { - String tooltipName; String color; int durability; float modifier; @@ -21,7 +20,16 @@ public ModDurability(ItemStack[] items, int effect, int dur, float mod, int leve durability = dur; modifier = mod; miningLevel = level; - tooltipName = tip; + tooltipName = c + k; + color = c; + } + + public ModDurability(ItemStack[] items, int effect, int dur, float mod, int level, String k, String c) { + super(items, effect, k); + durability = dur; + modifier = mod; + miningLevel = level; + tooltipName = c + k; color = c; } diff --git a/src/main/java/tconstruct/modifiers/tools/ModInteger.java b/src/main/java/tconstruct/modifiers/tools/ModInteger.java index cf74378a35a..210a2ea3589 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModInteger.java +++ b/src/main/java/tconstruct/modifiers/tools/ModInteger.java @@ -10,7 +10,6 @@ public class ModInteger extends ItemModifier { String color; - String tooltipName; int initialIncrease; int secondaryIncrease; diff --git a/src/main/java/tconstruct/modifiers/tools/ModLapis.java b/src/main/java/tconstruct/modifiers/tools/ModLapis.java index 7752ac330df..febbf421660 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModLapis.java +++ b/src/main/java/tconstruct/modifiers/tools/ModLapis.java @@ -10,17 +10,18 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EnumChatFormatting; import tconstruct.library.tools.ToolCore; public class ModLapis extends ItemModTypeFilter { - String tooltipName; int max = 450; public ModLapis(int effect, ItemStack[] items, int[] values) { super(effect, "Lapis", items, values); - tooltipName = "\u00a79Luck"; + this.color = EnumChatFormatting.BLUE.toString(); + this.tooltipName = color + "Luck"; } @Override @@ -49,8 +50,8 @@ public void modify(ItemStack[] input, ItemStack tool) { if (!tags.hasKey(key)) { tags.setBoolean(key, true); - String modName = "\u00a79Lapis (0/450)"; - int tooltipIndex = addToolTip(tool, "\u00a79Luck", modName); + String modName = this.color + "Lapis (0/450)"; + int tooltipIndex = addToolTip(tool, this.color + "Luck", modName); int[] keyPair = new int[] { 0, tooltipIndex }; tags.setIntArray(key, keyPair); @@ -164,7 +165,7 @@ public void addEnchantment(ItemStack tool, Enchantment enchant, int level) { void updateModTag(ItemStack tool, int[] keys) { NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool"); String tip = "ModifierTip" + keys[1]; - String modName = "\u00a79Lapis (" + keys[0] + "/" + max + ")"; + String modName = this.color + "Lapis (" + keys[0] + "/" + max + ")"; tags.setString(tip, modName); } diff --git a/src/main/java/tconstruct/modifiers/tools/ModPiston.java b/src/main/java/tconstruct/modifiers/tools/ModPiston.java index 5f4c005e452..5363e5c2ff8 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModPiston.java +++ b/src/main/java/tconstruct/modifiers/tools/ModPiston.java @@ -10,7 +10,6 @@ public class ModPiston extends ItemModTypeFilter { - String tooltipName; int max = 10; public ModPiston(int effect, ItemStack[] items, int[] values) { diff --git a/src/main/java/tconstruct/modifiers/tools/ModRedstone.java b/src/main/java/tconstruct/modifiers/tools/ModRedstone.java index 54055dfc601..fb899e3b923 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModRedstone.java +++ b/src/main/java/tconstruct/modifiers/tools/ModRedstone.java @@ -12,7 +12,6 @@ public class ModRedstone extends ItemModTypeFilter { - public String tooltipName; public int max = 50; public ModRedstone(int effect, ItemStack[] items, int[] values) { diff --git a/src/main/java/tconstruct/modifiers/tools/ModReinforced.java b/src/main/java/tconstruct/modifiers/tools/ModReinforced.java index dc975691464..d23e9a171b7 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModReinforced.java +++ b/src/main/java/tconstruct/modifiers/tools/ModReinforced.java @@ -2,6 +2,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; public class ModReinforced extends ModInteger { @@ -55,4 +56,20 @@ protected int addToolTip(ItemStack tool, String tooltip, String modifierTip) { } } } + + public static String getReinforcedString(int reinforced) { + if (reinforced > 9) return StatCollector.translateToLocal("tool.unbreakable"); + return StatCollector.translateToLocal("tool.reinforced") + " " + switch (reinforced) { + case 1 -> "I"; + case 2 -> "II"; + case 3 -> "III"; + case 4 -> "IV"; + case 5 -> "V"; + case 6 -> "VI"; + case 7 -> "VII"; + case 8 -> "VIII"; + case 9 -> "IX"; + default -> "X"; + }; + } } diff --git a/src/main/java/tconstruct/modifiers/tools/ModSmite.java b/src/main/java/tconstruct/modifiers/tools/ModSmite.java index 3502783059f..4f1cb3c82cd 100644 --- a/src/main/java/tconstruct/modifiers/tools/ModSmite.java +++ b/src/main/java/tconstruct/modifiers/tools/ModSmite.java @@ -5,7 +5,6 @@ public class ModSmite extends ItemModTypeFilter { - String tooltipName; int max = 36; String tagName; diff --git a/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java b/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java index fa6fbe3973a..7ae44a0c734 100644 --- a/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java +++ b/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java @@ -24,6 +24,7 @@ import tconstruct.library.util.HarvestLevels; import tconstruct.library.util.IToolPart; import tconstruct.library.util.LocalizedColors; +import tconstruct.modifiers.tools.ModReinforced; import tconstruct.tools.items.ToolPart; import tconstruct.util.config.PHConstruct; @@ -160,7 +161,7 @@ public void drawExtras(int recipe) { int abilityY = 85; if (crecipe.material.reinforced > 0) { GuiDraw.drawString( - getReinforcedString(crecipe.material.reinforced), + ModReinforced.getReinforcedString(crecipe.material.reinforced), 35, 85, LocalizedColors.MATERIAL_REINFORCED, @@ -286,42 +287,4 @@ public void loadUsageRecipes(ItemStack ingred) { super.loadUsageRecipes(ingred); } } - - public static String getReinforcedString(int reinforced) { - if (reinforced > 9) return "Unbreakable"; - String ret = "Reinforced "; - switch (reinforced) { - case 1: - ret += "I"; - break; - case 2: - ret += "II"; - break; - case 3: - ret += "III"; - break; - case 4: - ret += "IV"; - break; - case 5: - ret += "V"; - break; - case 6: - ret += "VI"; - break; - case 7: - ret += "VII"; - break; - case 8: - ret += "VIII"; - break; - case 9: - ret += "IX"; - break; - default: - ret += "X"; - break; - } - return ret; - } } diff --git a/src/main/java/tconstruct/tools/TinkerTools.java b/src/main/java/tconstruct/tools/TinkerTools.java index 079f17fad11..76254241236 100644 --- a/src/main/java/tconstruct/tools/TinkerTools.java +++ b/src/main/java/tconstruct/tools/TinkerTools.java @@ -22,7 +22,6 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.StatCollector; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.ShapedOreRecipe; @@ -673,16 +672,8 @@ private void addRecipesForToolBuilder() { ItemStack diamond = new ItemStack(Items.diamond); ModifyBuilder.registerModifier(new ModToolRepair()); - ModifyBuilder.registerModifier( - new ModDurability( - new ItemStack[] { diamond }, - 0, - 500, - 0f, - 3, - "Diamond", - "\u00a7b" + StatCollector.translateToLocal("modifier.tool.diamond"), - "\u00a7b")); + ModifyBuilder + .registerModifier(new ModDurability(new ItemStack[] { diamond }, 0, 500, 0f, 3, "Diamond", "\u00a7b")); ModifyBuilder.registerModifier( new ModDurability( new ItemStack[] { new ItemStack(Items.emerald) }, @@ -691,7 +682,6 @@ private void addRecipesForToolBuilder() { 0.5f, 2, "Emerald", - "\u00a72" + StatCollector.translateToLocal("modifier.tool.emerald"), "\u00a72")); ItemStack redstoneItem = new ItemStack(Items.redstone); @@ -706,7 +696,7 @@ private void addRecipesForToolBuilder() { "Moss", 3, "\u00a72", - StatCollector.translateToLocal("modifier.tool.moss"))); + "moss")); ItemStack blazePowder = new ItemStack(Items.blaze_powder); ModifyBuilder.registerModifier(new ModBlaze(7, new ItemStack[] { blazePowder }, new int[] { 1 })); ModifyBuilder.registerModifier( @@ -715,7 +705,7 @@ private void addRecipesForToolBuilder() { 6, "Lava", "\u00a74", - StatCollector.translateToLocal("modifier.tool.lava"))); + "lava")); ModifyBuilder.registerModifier( new ModInteger( new ItemStack[] { new ItemStack(TinkerTools.materials, 1, 8) }, @@ -723,7 +713,7 @@ private void addRecipesForToolBuilder() { "Necrotic", 1, "\u00a78", - StatCollector.translateToLocal("modifier.tool.necro"))); + "necro")); ModifyBuilder.registerModifier( new ModExtraModifier(new ItemStack[] { diamond, new ItemStack(Blocks.gold_block) }, "Tier1Free")); diff --git a/src/main/java/tconstruct/tools/ToolProxyClient.java b/src/main/java/tconstruct/tools/ToolProxyClient.java index 40132c9d79e..696cd16a5c3 100644 --- a/src/main/java/tconstruct/tools/ToolProxyClient.java +++ b/src/main/java/tconstruct/tools/ToolProxyClient.java @@ -36,6 +36,12 @@ import tconstruct.client.entity.projectile.LaunchedItemRender; import tconstruct.client.pages.MaterialPage; import tconstruct.client.pages.ModifierPage; +import tconstruct.client.pages.NavigationPage; +import tconstruct.client.pages.TiCCoverPage; +import tconstruct.client.pages.TiCCraftingPage; +import tconstruct.client.pages.TiCMaterialPage; +import tconstruct.client.pages.TiCPicturePage; +import tconstruct.client.pages.TiCTextPage; import tconstruct.client.pages.ToolPage; import tconstruct.common.TProxyCommon; import tconstruct.library.TConstructRegistry; @@ -97,11 +103,14 @@ public void registerRenderer() { RenderingRegistry .registerEntityRenderingHandler(LaunchedPotion.class, new LaunchedItemRender(Items.potionitem, 16384)); RenderingRegistry.registerEntityRenderingHandler(DaggerEntity.class, new DaggerEntityRenderer()); - // RenderingRegistry.registerEntityRenderingHandler(DaggerEntity.class, new DaggerRenderCustom()); - // RenderingRegistry.registerEntityRenderingHandler(ArrowEntity.class, new ArrowRenderCustom()); + // RenderingRegistry.registerEntityRenderingHandler(DaggerEntity.class, new + // DaggerRenderCustom()); + // RenderingRegistry.registerEntityRenderingHandler(ArrowEntity.class, new + // ArrowRenderCustom()); RenderingRegistry.registerEntityRenderingHandler(FancyEntityItem.class, new FancyItemRender()); - // MinecraftForgeClient.registerItemRenderer(TinkerTools.shortbow, new CustomBowRenderer()); + // MinecraftForgeClient.registerItemRenderer(TinkerTools.shortbow, new + // CustomBowRenderer()); FlexibleToolRenderer renderer = new FlexibleToolRenderer(); MinecraftForgeClient.registerItemRenderer(TinkerTools.pickaxe, renderer); MinecraftForgeClient.registerItemRenderer(TinkerTools.shovel, renderer); @@ -122,7 +131,8 @@ public void registerRenderer() { MinecraftForgeClient.registerItemRenderer(TinkerTools.scythe, renderer); MinecraftForgeClient.registerItemRenderer(TinkerTools.dagger, renderer); // ToolCoreRenderer daggerRenderer = new ToolCoreRenderer(true); - // MinecraftForgeClient.registerItemRenderer(TinkerTools.dagger, daggerRenderer); // todo proper renderer + // MinecraftForgeClient.registerItemRenderer(TinkerTools.dagger, + // daggerRenderer); // todo proper renderer TileEntityRendererDispatcher.instance.mapSpecialRenderers.put(BattlesignLogic.class, new BattlesignTesr()); } @@ -207,11 +217,15 @@ public void registerManualIcons() { new ItemStack(TinkerTools.toolRod, 1, 11), null, "")); - // MantleClientRegistry.registerManualIcon("shortbowIcon", ToolBuilder.instance.buildTool(new - // ItemStack(TinkerTools.toolRod, 1, 10), new ItemStack(TinkerWeaponry.bowstring, 1, 0), new + // MantleClientRegistry.registerManualIcon("shortbowIcon", + // ToolBuilder.instance.buildTool(new + // ItemStack(TinkerTools.toolRod, 1, 10), new + // ItemStack(TinkerWeaponry.bowstring, 1, 0), new // ItemStack(TinkerTools.toolRod, 1, 12), "")); - // MantleClientRegistry.registerManualIcon("arrowIcon", ToolBuilder.instance.buildTool(new - // ItemStack(TinkerWeaponry.arrowhead, 1, 10), new ItemStack(TinkerTools.toolRod, 1, 11), new + // MantleClientRegistry.registerManualIcon("arrowIcon", + // ToolBuilder.instance.buildTool(new + // ItemStack(TinkerWeaponry.arrowhead, 1, 10), new + // ItemStack(TinkerTools.toolRod, 1, 11), new // ItemStack(TinkerWeaponry.fletching, 1, 0), "")); MantleClientRegistry.registerManualIcon( @@ -321,6 +335,13 @@ public void registerManualIcons() { MProxyClient.registerManualPage("materialstats", MaterialPage.class); MProxyClient.registerManualPage("toolpage", ToolPage.class); MProxyClient.registerManualPage("modifier", ModifierPage.class); + + MProxyClient.registerManualPage("cover", TiCCoverPage.class); + MProxyClient.registerManualPage("tictext", TiCTextPage.class); + MProxyClient.registerManualPage("ticcrafting", TiCCraftingPage.class); + MProxyClient.registerManualPage("navigation", NavigationPage.class); + MProxyClient.registerManualPage("ticpicture", TiCPicturePage.class); + MProxyClient.registerManualPage("ticmaterial", TiCMaterialPage.class); } void registerManualRecipes() { @@ -426,7 +447,12 @@ void registerManualRecipes() { ironblock, ironblock, null, - ironblock); // TODO: Alternate recipe for Smeltery disabled + ironblock); // TODO: + // Alternate + // recipe + // for + // Smeltery + // disabled MantleClientRegistry.registerManualLargeRecipe( "slimymud", diff --git a/src/main/java/tconstruct/tools/gui/TiCGuiManual.java b/src/main/java/tconstruct/tools/gui/TiCGuiManual.java deleted file mode 100644 index 793890ef2ee..00000000000 --- a/src/main/java/tconstruct/tools/gui/TiCGuiManual.java +++ /dev/null @@ -1,215 +0,0 @@ -package tconstruct.tools.gui; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiLabel; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import mantle.books.BookData; -import mantle.client.MProxyClient; -import mantle.client.RenderItemCopy; -import mantle.client.SmallFontRenderer; -import mantle.client.gui.GuiManual; -import mantle.client.gui.TurnPageButton; -import mantle.client.pages.BookPage; -import tconstruct.TConstruct; - -@SideOnly(Side.CLIENT) -public class TiCGuiManual extends GuiManual { - - ItemStack itemstackBook; - Document manual; - public RenderItemCopy renderitem = new RenderItemCopy(); - int bookImageWidth = 206; - int bookImageHeight = 200; - int bookTotalPages = 1; - int currentPage; - int maxPages; - BookData bData; - - private TurnPageButton buttonNextPage; - private TurnPageButton buttonPreviousPage; - private static ResourceLocation bookRight;// = new ResourceLocation("mantle", "textures/gui/bookright.png"); - private static ResourceLocation bookLeft;// = new ResourceLocation("mantle", "textures/gui/bookleft.png"); - - BookPage pageLeft; - BookPage pageRight; - - public SmallFontRenderer fonts = MProxyClient.smallFontRenderer; - - public TiCGuiManual(ItemStack stack, BookData data) { - super(stack, data); - this.mc = Minecraft.getMinecraft(); - this.itemstackBook = stack; - currentPage = 0; // Stack page - manual = data.getDoc(); - if (data.font != null) this.fonts = data.font; - bookLeft = data.leftImage; - bookRight = data.rightImage; - this.bData = data; - - // renderitem.renderInFrame = true; - } - - /* - * @Override public void setWorldAndResolution (Minecraft minecraft, int w, int h) { this.guiParticles = new - * GuiParticle(minecraft); this.mc = minecraft; this.width = w; this.height = h; this.buttonList.clear(); - * this.initGui(); } - */ - - @SuppressWarnings("unchecked") - public void initGui() { - maxPages = manual.getElementsByTagName("page").getLength(); - ticUpdateText(); - int xPos = (this.width) / 2; // TODO Width? - // TODO buttonList - this.buttonList.add( - this.buttonNextPage = new TurnPageButton( - 1, - xPos + bookImageWidth - 50, - (this.height + this.bookImageHeight) / 2 - 28, - true, - bData)); - this.buttonList.add( - this.buttonPreviousPage = new TurnPageButton( - 2, - xPos - bookImageWidth + 24, - (this.height + this.bookImageHeight) / 2 - 28, - false, - bData)); - updateButtonVisibility(); - } - - private void updateButtonVisibility() { - buttonPreviousPage.visible = currentPage > 0; - buttonNextPage.visible = currentPage < maxPages - 2; - } - - protected void actionPerformed(GuiButton button) { - if (button.enabled) { - changePage(button.id); - updateButtonVisibility(); - ticUpdateText(); - } - } - - void ticUpdateText() { - if (maxPages % 2 == 1) { - if (currentPage > maxPages) currentPage = maxPages; - } else { - if (currentPage >= maxPages) currentPage = maxPages - 2; - } - if (currentPage % 2 == 1) currentPage--; - if (currentPage < 0) currentPage = 0; - - NodeList nList = manual.getElementsByTagName("page"); - - Node node = nList.item(currentPage); - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) node; - Class clazz = MProxyClient.getPageClass(element.getAttribute("type")); - if (clazz != null) { - try { - pageLeft = clazz.getDeclaredConstructor().newInstance(); - pageLeft.init(this, 0); - pageLeft.readPageFromXML(element); - } catch (Exception e) { - TConstruct.logger.error(e); - } - } else { - pageLeft = null; - } - } - - node = nList.item(currentPage + 1); - if (node != null && node.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) node; - Class clazz = MProxyClient.getPageClass(element.getAttribute("type")); - if (clazz != null) { - try { - pageRight = clazz.getDeclaredConstructor().newInstance(); - pageRight.init(this, 1); - pageRight.readPageFromXML(element); - } catch (Exception e) { - TConstruct.logger.error(e); - } - } else { - pageLeft = null; - } - } else { - pageRight = null; - } - } - - private void changePage(int buttonId) { - if (buttonId == 1) { - currentPage += 2; - } - if (buttonId == 2) { - currentPage -= 2; - } - } - - public void drawScreen(int par1, int par2, float par3) { - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - this.mc.getTextureManager().bindTexture(bookRight); - - // aligen to center - int localWidth = (this.width / 2); - int localHeight = ((this.height - this.bookImageHeight) / 2); - - this.drawTexturedModalRect(localWidth, localHeight, 0, 0, this.bookImageWidth, this.bookImageHeight); - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - this.mc.getTextureManager().bindTexture(bookLeft); - localWidth = localWidth - this.bookImageWidth; - this.drawTexturedModalRect( - localWidth, - localHeight, - 256 - this.bookImageWidth, - 0, - this.bookImageWidth, - this.bookImageHeight); - - this.drawButtons(par1, par2); - - if (pageLeft != null) pageLeft.renderBackgroundLayer(localWidth + 16, localHeight + 12); - if (pageRight != null) pageRight.renderBackgroundLayer(localWidth + 220, localHeight + 12); - if (pageLeft != null) pageLeft.renderContentLayer(localWidth + 16, localHeight + 12, bData.isTranslatable); - if (pageRight != null) pageRight.renderContentLayer(localWidth + 220, localHeight + 12, bData.isTranslatable); - - } - - /** - * copy from {@link net.minecraft.client.gui.GuiScreen#drawScreen(int, int, float)} - */ - public void drawButtons(int mouseX, int mouseY) { - // copy from @GuiScreen.drawScreen - int k; - - for (k = 0; k < this.buttonList.size(); ++k) { - ((GuiButton) this.buttonList.get(k)).drawButton(this.mc, mouseX, mouseY); - } - - for (k = 0; k < this.labelList.size(); ++k) { - ((GuiLabel) this.labelList.get(k)).func_146159_a(this.mc, mouseX, mouseY); - } - } - - public Minecraft getMC() { - return mc; - } - - public boolean doesGuiPauseGame() { - return false; - } -} diff --git a/src/main/java/tconstruct/tools/items/Manual.java b/src/main/java/tconstruct/tools/items/Manual.java index e2c120aa40b..05fb4d3eb84 100644 --- a/src/main/java/tconstruct/tools/items/Manual.java +++ b/src/main/java/tconstruct/tools/items/Manual.java @@ -17,14 +17,15 @@ import tconstruct.TConstruct; import tconstruct.achievements.TAchievements; import tconstruct.library.TConstructRegistry; -import tconstruct.tools.gui.TiCGuiManual; +import tconstruct.library.util.TiCGuiManual; import tconstruct.util.McTextFormatter; public class Manual extends CraftingItem { - static String[] name = new String[] { "beginner", "toolstation", "smeltery", "diary", "weaponry" }; + static String[] name = new String[] { "beginner", "toolstation", "smeltery", "diary", "weaponry", + "materialsandyou" }; static String[] textureName = new String[] { "tinkerbook_diary", "tinkerbook_toolstation", "tinkerbook_smeltery", - "tinkerbook_blue", "tinkerbook_green" }; + "tinkerbook_blue", "tinkerbook_green", "tinkerbook_materialsandyou" }; public Manual() { super(name, textureName, "", "tinker", TConstructRegistry.materialTab); @@ -55,8 +56,10 @@ private static String getBookName(int bookItemDamage) { case 0 -> "tconstruct.manual.beginner"; case 1 -> "tconstruct.manual.toolstation"; case 2 -> "tconstruct.manual.smeltery"; + case 3 -> "tconstruct.manual.diary"; case 4 -> "tconstruct.manual.weaponry"; - default -> "tconstruct.manual.diary"; + case 5 -> "tconstruct.manual.materialsandyou"; + default -> "tconstruct.manual.materialsandyou"; }; } @@ -76,9 +79,15 @@ public void addInformation(ItemStack stack, EntityPlayer player, List li case 4: list.add(McTextFormatter.addItalic(StatCollector.translateToLocal("manual4.tooltip"))); break; - default: + case 5: list.add(McTextFormatter.addItalic(StatCollector.translateToLocal("manual5.tooltip"))); break; + case 6: + list.add(McTextFormatter.addItalic(StatCollector.translateToLocal("manual6.tooltip"))); + break; + default: + list.add(McTextFormatter.addItalic(StatCollector.translateToLocal("manual6.tooltip"))); + break; } } } diff --git a/src/main/java/tconstruct/tools/items/ManualInfo.java b/src/main/java/tconstruct/tools/items/ManualInfo.java index 94467d6d023..3453c57f042 100644 --- a/src/main/java/tconstruct/tools/items/ManualInfo.java +++ b/src/main/java/tconstruct/tools/items/ManualInfo.java @@ -7,10 +7,10 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; -import mantle.books.BookData; import mantle.books.BookDataStore; import tconstruct.TConstruct; import tconstruct.client.TProxyClient; +import tconstruct.library.util.TiCBookData; /** * This class is now just a constructor with side effects, so a glorified method call. TODO: Clean up when breaking API @@ -20,45 +20,60 @@ public class ManualInfo { public ManualInfo() { Side side = FMLCommonHandler.instance().getEffectiveSide(); - initManual( - new BookData(), - "tconstruct.manual.beginner", - "\u00a7o" + StatCollector.translateToLocal("manual1.tooltip"), - side == Side.CLIENT ? TProxyClient.volume1 : null, - "tinker:tinkerbook_diary"); - initManual( - new BookData(), - "tconstruct.manual.toolstation", - "\u00a7o" + StatCollector.translateToLocal("manual2.tooltip"), - side == Side.CLIENT ? TProxyClient.volume2 : null, - "tinker:tinkerbook_toolstation"); - initManual( - new BookData(), - "tconstruct.manual.smeltery", - "\u00a7o" + StatCollector.translateToLocal("manual3.tooltip"), - side == Side.CLIENT ? TProxyClient.smelter : null, - "tinker:tinkerbook_smeltery"); - initManual( - new BookData(), - "tconstruct.manual.diary", - "\u00a7o" + StatCollector.translateToLocal("manual4.tooltip"), - side == Side.CLIENT ? TProxyClient.diary : null, - "tinker:tinkerbook_blue"); - initManual( - new BookData(), - "tconstruct.manual.weaponry", - "\u00a7o" + StatCollector.translateToLocal("manual5.tooltip"), - side == Side.CLIENT ? TProxyClient.weaponry : null, - "tinker:tinkerbook_green"); + BookDataStore.addBook( + initManual( + new TiCBookData(), + "tconstruct.manual.beginner", + "\u00a7o" + StatCollector.translateToLocal("manual1.tooltip"), + side == Side.CLIENT ? TProxyClient.volume1 : null, + "tinker:tinkerbook_diary", + 0xD89A1D)); + BookDataStore.addBook( + initManual( + new TiCBookData(), + "tconstruct.manual.toolstation", + "\u00a7o" + StatCollector.translateToLocal("manual2.tooltip"), + side == Side.CLIENT ? TProxyClient.volume2 : null, + "tinker:tinkerbook_toolstation", + 0xD61E17)); + BookDataStore.addBook( + initManual( + new TiCBookData(), + "tconstruct.manual.smeltery", + "\u00a7o" + StatCollector.translateToLocal("manual3.tooltip"), + side == Side.CLIENT ? TProxyClient.smelter : null, + "tinker:tinkerbook_smeltery", + 0xB6B6B6)); + BookDataStore.addBook( + initManual( + new TiCBookData(), + "tconstruct.manual.diary", + "\u00a7o" + StatCollector.translateToLocal("manual4.tooltip"), + side == Side.CLIENT ? TProxyClient.diary : null, + "tinker:tinkerbook_blue", + 0x21BBDC)); + BookDataStore.addBook( + initManual( + new TiCBookData(), + "tconstruct.manual.weaponry", + "\u00a7o" + StatCollector.translateToLocal("manual5.tooltip"), + side == Side.CLIENT ? TProxyClient.weaponry : null, + "tinker:tinkerbook_green", + 0x27CD1B)); + + BookDataStore.addBook( + initManual( + new TiCBookData(), + "tconstruct.manual.materialsandyou", + "\u00a7o" + StatCollector.translateToLocal("manual6.tooltip"), + side == Side.CLIENT ? TProxyClient.materialsandyou : null, + "tinker:tinkerbook_materialsandyou", + 0xEB00EF)); } - public BookData initManual(BookData data, String unlocName, String toolTip, Document xmlDoc, String itemImage) { - data.unlocalizedName = unlocName; - data.toolTip = unlocName; - data.modID = TConstruct.modID; - data.itemImage = new ResourceLocation(data.modID, itemImage); - data.doc = xmlDoc; - BookDataStore.addBook(data); - return data; + public TiCBookData initManual(TiCBookData data, String unlocName, String toolTip, Document xmlDoc, String itemImage, + int color) { + return data.setUnlocalizedName(unlocName).setToolTip(unlocName).setModID(TConstruct.modID) + .setItemImage(new ResourceLocation(data.modID, itemImage)).setDoc(xmlDoc).setBookColor(color); } } diff --git a/src/main/java/tconstruct/util/FontColorHelper.java b/src/main/java/tconstruct/util/FontColorHelper.java new file mode 100644 index 00000000000..93426ecd5c0 --- /dev/null +++ b/src/main/java/tconstruct/util/FontColorHelper.java @@ -0,0 +1,112 @@ +package tconstruct.util; + +import java.awt.Color; + +public class FontColorHelper { + + private static final double CONTRAST_THRESHOLD = 3; + + public static boolean isReadable(int bgRgb, int fgRgb, double threshold) { + double bgLum = getRelativeLuminance(bgRgb); + double fgLum = getRelativeLuminance(fgRgb); + double contrast = getContrastRatio(bgLum, fgLum); + return contrast >= threshold; + } + + public static boolean isReadable(int bgRgb, int fgRgb) { + return isReadable(bgRgb, fgRgb, CONTRAST_THRESHOLD); + } + + public static int adjustForegroundKeepHue(int bgRgb, int fgRgb, double threshold) { + if (isReadable(bgRgb, fgRgb, threshold)) { + return fgRgb; + } + + float[] fgHsv = rgbToHsv(fgRgb); + + float hue = fgHsv[0]; + float saturation = fgHsv[1]; + float value = fgHsv[2]; + + double bgLum = getRelativeLuminance(bgRgb); + boolean brightBackground = bgLum > 0.5; + + final float VALUE_MIN = 0.0f; + final float VALUE_MAX = 1.0f; + float step = 0.05f; + int maxIterations = 20; + int iter = 0; + + float newValue = value; + while (iter < maxIterations) { + int candidateRgb = hsvToRgb(hue, saturation, newValue); + if (isReadable(bgRgb, candidateRgb, threshold)) { + return candidateRgb; + } + if (brightBackground) { + newValue -= step; + if (newValue < VALUE_MIN) { + newValue = VALUE_MIN; + return hsvToRgb(hue, saturation, newValue); + } + } else { + newValue += step; + if (newValue > VALUE_MAX) { + newValue = VALUE_MAX; + return hsvToRgb(hue, saturation, newValue); + } + } + iter++; + if (iter > 10) step = 0.01f; + } + return hsvToRgb(hue, saturation, newValue); + } + + public static int adjustForegroundKeepHue(int bgRgb, int fgRgb) { + return adjustForegroundKeepHue(bgRgb, fgRgb, CONTRAST_THRESHOLD); + } + + private static double getRelativeLuminance(int rgb) { + int r = (rgb >> 16) & 0xFF; + int g = (rgb >> 8) & 0xFF; + int b = rgb & 0xFF; + return getRelativeLuminance(r, g, b); + } + + private static double getRelativeLuminance(int r, int g, int b) { + double rs = linearize(r / 255.0); + double gs = linearize(g / 255.0); + double bs = linearize(b / 255.0); + return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs; + } + + private static double linearize(double channel) { + if (channel <= 0.03928) { + return channel / 12.92; + } + return Math.pow((channel + 0.055) / 1.055, 2.4); + } + + private static double getContrastRatio(double lum1, double lum2) { + double lighter = Math.max(lum1, lum2); + double darker = Math.min(lum1, lum2); + return (lighter + 0.05) / (darker + 0.05); + } + + private static float[] rgbToHsv(int rgb) { + int r = (rgb >> 16) & 0xFF; + int g = (rgb >> 8) & 0xFF; + int b = rgb & 0xFF; + float[] hsv = new float[3]; + Color.RGBtoHSB(r, g, b, hsv); + hsv[0] = hsv[0] * 360; + return hsv; + } + + private static int hsvToRgb(float hue, float saturation, float value) { + float h = hue / 360.0f; + int rgb = Color.HSBtoRGB(h, saturation, value); + return rgb & 0x00FFFFFF; + } + +} diff --git a/src/main/java/tconstruct/util/TiCRecipeHolder.java b/src/main/java/tconstruct/util/TiCRecipeHolder.java new file mode 100644 index 00000000000..13c4c3f65f7 --- /dev/null +++ b/src/main/java/tconstruct/util/TiCRecipeHolder.java @@ -0,0 +1,129 @@ +package tconstruct.util; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.item.crafting.ShapelessRecipes; +import net.minecraftforge.oredict.ShapedOreRecipe; +import net.minecraftforge.oredict.ShapelessOreRecipe; + +public class TiCRecipeHolder { + + private static final Field WIDTH_FIELD; + private static final Field HEIGHT_FIELD; + + static { + try { + WIDTH_FIELD = ShapedOreRecipe.class.getDeclaredField("width"); + HEIGHT_FIELD = ShapedOreRecipe.class.getDeclaredField("height"); + + WIDTH_FIELD.setAccessible(true); + HEIGHT_FIELD.setAccessible(true); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public enum RecipeType { + + ShapedOre("ShapedOreRecipe"), + ShapelessOre("ShapelessOreRecipe"), + Shaped("ShapedRecipes"), + Shapeless("ShapelessRecipes"), + Furnace("FurnaceRecipes"), + ToolStation("ToolStationRecipe"), + ToolForge("ToolForgeRecipe"); + + public String type; + + private RecipeType(String t) { + this.type = t; + } + + } + + private static int getSize(ShapedOreRecipe sor) { + try { + return Math.max(WIDTH_FIELD.getInt(sor), HEIGHT_FIELD.getInt(sor)); + } catch (IllegalAccessException e) { + return 0; + } + } + + public final RecipeType recipeType; + public final ItemStack outputStack; + public final ItemStack[][] inputStacks; + public final int varietyOfOre; + public final int recipeSize; + + public TiCRecipeHolder(IRecipe recipe) { + int maxRecipesSize = 0; + RecipeType craftingType = null; + ItemStack target = recipe.getRecipeOutput(); + ItemStack[][] inputs = new ItemStack[0][]; + int recipeSize = 0; + List a = new ArrayList<>(); + if (recipe instanceof ShapedOreRecipe sor) { + craftingType = RecipeType.ShapedOre; + for (Object b : Arrays.asList(sor.getInput())) { + if (b instanceof Listl) { + maxRecipesSize = Math.max(maxRecipesSize, l.size()); + a.add(l.toArray(new ItemStack[] {})); + } else if (b instanceof ItemStack l) { + a.add(new ItemStack[] { l }); + } else { + a.add(null); + } + } + inputs = a.toArray(inputs); + recipeSize = getSize(sor); + } else if (recipe instanceof ShapelessOreRecipe sor) { + craftingType = RecipeType.ShapelessOre; + for (Object b : sor.getInput()) { + if (b instanceof Listl) { + maxRecipesSize = Math.max(maxRecipesSize, l.size()); + a.add(l.toArray(new ItemStack[] {})); + } else if (b instanceof ItemStack l) { + a.add(new ItemStack[] { l }); + } + } + inputs = a.toArray(inputs); + } else if (recipe instanceof ShapedRecipes sr) { + craftingType = RecipeType.Shaped; + inputs = Arrays.asList(sr.recipeItems).stream().map(i -> new ItemStack[] { i }).collect(Collectors.toList()) + .toArray(inputs); + recipeSize = Math.max(sr.recipeWidth, sr.recipeHeight); + } else if (recipe instanceof ShapelessRecipes sr) { + craftingType = RecipeType.Shapeless; + inputs = sr.recipeItems.stream().map(i -> new ItemStack[] { i }).collect(Collectors.toList()) + .toArray(inputs); + } + recipeSize = recipeSize == 0 ? (inputs.length > 4 ? 3 : 2) : recipeSize; + + this.recipeType = craftingType; + this.outputStack = target; + this.inputStacks = inputs; + this.varietyOfOre = maxRecipesSize; + this.recipeSize = recipeSize; + + } + + public TiCRecipeHolder(ItemStack input, ItemStack output) { + this(new ItemStack[][] { { input } }, output, RecipeType.Furnace); + } + + public TiCRecipeHolder(ItemStack[][] input, ItemStack output, RecipeType t) { + this.inputStacks = input; + this.outputStack = output; + this.varietyOfOre = 1; + this.recipeSize = 0; + this.recipeType = t; + } + +} diff --git a/src/main/resources/assets/tinker/.vscode/settings.json b/src/main/resources/assets/tinker/.vscode/settings.json new file mode 100644 index 00000000000..d10522852b3 --- /dev/null +++ b/src/main/resources/assets/tinker/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.formatOnSave": false, + "editor.formatOnPaste": false +} diff --git a/src/main/resources/assets/tinker/lang/en_US.lang b/src/main/resources/assets/tinker/lang/en_US.lang index 63cc3221bb0..b2c2bd0eb73 100644 --- a/src/main/resources/assets/tinker/lang/en_US.lang +++ b/src/main/resources/assets/tinker/lang/en_US.lang @@ -516,6 +516,7 @@ item.tconstruct.manual.toolstation.name=Materials and You: Volume 2 item.tconstruct.manual.smeltery.name=Mighty Smelting item.tconstruct.manual.diary.name=Diary of a Tinker item.tconstruct.manual.weaponry.name=Tinkers' Weaponry +item.tconstruct.manual.materialsandyou.name=Materials and You item.tconstruct.bucket.name=Bucket item.tconstruct.bucket.Iron.name=Molten Iron Bucket @@ -816,6 +817,7 @@ manual2.tooltip=By: Skyla manual3.tooltip=By: Thruul M'gon manual4.tooltip=By: Sheriff Bownana manual5.tooltip=By: Nameless Tinker +manual5.tooltip=By: MCTBL searedtank1.tooltip=Contains searedtank2.tooltip=Keeps any fluids it has when harvested searedtank3.tooltip=Heart of the Smeltery @@ -928,6 +930,13 @@ gui.toolstation21=Ammo: gui.toolstation22=Break Chance: gui.toolstation23=Max. Attack: +gui.partcrafter.durability.desc=The base-value for durability calculations.\nUsually an integral part to the overall durability of a tool. +gui.partcrafter.mininglevel.desc=What range of blocks a tool with a tool head of this material can mine. +gui.partcrafter.miningspeed.desc=How fast a tool with a tool head of this material can mine blocks.\nMay be influenced by other toolparts. +gui.partcrafter.attack.desc=Base value for attack calculations.\nThe end result depends on the tool itself and the other components used. +gui.partcrafter.handlemodifier.desc=How suitable the tool material is as a handle.\nThe total durability of the tool will be multiplied by this. +gui.partcrafter.drawspeed.desc=How fast you can draw the bow. + gui.partcrafter.durability=Durability: %s gui.partcrafter.mininglevel=Mining Level: %s gui.partcrafter.miningspeed=Mining Speed: %s @@ -977,13 +986,16 @@ gui.toolstation.javelin.desc=Ranged Melee weapon hybrid. Potent as a melee weapo material.alumite=Alumite material.ardite=Ardite material.ardite.ability=Stonebound +material.ardite.ability.desc=The tool mines faster as it wears out, but does less damage material.blueslime=Blue Slime material.blueslime.ability=Slimy +material.blueslime.ability.desc=Randomly spawn Blue Slime around you when you are useing tool made by this material material.blueslime.display=Slime material.bone=Bone material.bronze=Bronze material.cactus=Cactus material.cactus.ability=Jagged +material.cactus.ability.desc=The tool attacks with does more damage as it wears out, but mines slower material.cobalt=Cobalt material.copper=Copper material.flint=Flint @@ -991,21 +1003,32 @@ material.iron=Iron material.manyullyn=Manyullyn material.netherrack=Netherrack material.netherrack.ability=Stonebound +material.netherrack.ability.desc=The tool mines faster as it wears out, but does less damage material.obsidian=Obsidian material.paper=Paper material.paper.ability=Writable +material.paper.ability.desc=One extra modifier per piece material.pigiron=Pig Iron material.pigiron.ability=Tasty +material.pigiron.ability.desc=Sometimes drops food items material.slime=Slime material.slime.ability=Slimy +material.slime.ability.desc=Randomly spawn Slime around you when you are useing tool made by this material material.steel=Steel material.stone=Stone material.stone.ability=Stonebound +material.stone.ability.desc=The tool mines faster as it wears out, but does less damage material.thaumium=Thaumium material.thaumium.ability=Thaumic +material.thaumium.ability.desc=Half extra modifier per piece material.wood=Wood material.wood.display=Wooden +tool.reinforced=Reinforced +tool.reinforced.desc=10% chance per level of not using durability +tool.unbreakable=Unbreakable +tool.nodesc=There has no desc for %s + creativeModLock.tooltip=Target Lock: attribute.name.ammo.attackDamage=Base Damage @@ -1105,9 +1128,6 @@ gadgets.slime_boots.tooltip1=Boooounce! gadgets.slime_boots.tooltip2=Hold gadgets.slime_boots.tooltip3= to stop bouncing. -tool.reinforced=Reinforced -tool.unbreakable=Unbreakable - modifier.tool.diamond=Durability +500 modifier.tool.emerald=Durability +50% modifier.tool.haste=Haste @@ -1178,6 +1198,15 @@ modifier.tooltip.ThaumicSenses=Thaumic Senses modifier.tooltip.Triple-Jump=Triple-Jump modifier.tooltip.ThaumicVision=Thaumic Vision modifier.tooltip.Water-Walking=Water-Walking +modifier.tooltip.Auto-Repair=Auto-Repair +modifier.tooltip.Diamond=Durability +500 +modifier.tooltip.Emerald=Durability +50% +modifier.tooltip.haste=Haste +modifier.tooltip.lava=Auto-Smelt +modifier.tooltip.moss=Auto-Repair +modifier.tooltip.necro=Life Steal +modifier.tooltip.blaze=Fiery +modifier.tooltip.Reinforced=Reinforced tile.LavaTank.name=Seared Tank option.tcon.searedtank=Seared Tank @@ -1195,3 +1224,71 @@ tconstruct.mobsinfocompat.tinkers_construct_beheading_1=If you are using a Cleav #Baubles compat (Baubles Expanded already has the relevant localizations) baubletype.any=Equippable in a §aRing§7 slot + + +#manual button +tconstruct.manual.button.tooltip.nextPage=Next Page +tconstruct.manual.button.tooltip.previousPage=Previous Page +tconstruct.manual.button.tooltip.backToJumpFrom=Back Ward +tconstruct.manual.button.tooltip.homePage=Home Page + + +#manual text +tconstruct.manual.materialsandyou.homepage=Materials and You\nThis is all of what you need in TiC\nBy MCTBL +tconstruct.manual.materialsandyou.jumptointro=Introduce +tconstruct.manual.materialsandyou.jumptotools=Tools +tconstruct.manual.materialsandyou.jumptomaterials=Materials +tconstruct.manual.materialsandyou.jumptomodifies=Modifies +tconstruct.manual.materialsandyou.jumptosmeltery=Smeltery +tconstruct.manual.materialsandyou.jumptobowmaterials=Bow Materials + + +tconstruct.manual.materialsandyou.welcome1=Welcome to the §mfirst§r second edition of Materials and You: Surviving the first day and beyond. Within these pages you will find the first steps to making the tools and materials you need to survive.\n\nThis book is a magic copy; it updates whenever the original has been modified. Check back occasionally for information on new things. +tconstruct.manual.materialsandyou.welcome2=The first step in making tools is crafting a blank pattern. It is a blank slate to stamp a shape into, providing a reference for future creations. The patterns are shaped on the Stencil Table or are used as tabletops.\n\nYou can then shape a material in a part builder with the pattern, then combine parts in the tool station. Patterns can be stored and accessed in the pattern chest.\n\nTogether these make the Tool Workshop. It is recommended you keep all of these nearby when using any of them. +tconstruct.manual.materialsandyou.oreberrydesc=Oreberry Bushes\n\nSometime in your travels you will happen upon the bush known as the Oreberry. They grow underground in dark areas, and require close to complete darkness to produce anything.\n\nThe berries can be melted down into nuggets and ingots, making them an invaluable source of metals. +tconstruct.manual.materialsandyou.oreberrypic=Oreberries in their natural environment +tconstruct.manual.materialsandyou.slimechannels=Slime Channels\n\nSlime channels are useful for moving items or entities around. They are used as a sort of easily placeable water and can be paired with bounce pads for best effect. +tconstruct.manual.materialsandyou.trap=A few traps or blockades may help with your early survival experience +tconstruct.manual.materialsandyou.smelterydesc=Once you're well established, you can begin to process metals in a more efficient manner. The scope of the smeltery is beyond this volume, but a few recipes will help you get started.\n\nNote: The Smeltery is required to process all metals, including iron. +tconstruct.manual.materialsandyou.makenewbook=If you ever find yourself without this book, a new one is simple to make. Other books can be made from this one as well. + + +tconstruct.manual.materialsandyou.tool.pickaxe=The Pickaxe is a precise mining tool. It is effective on stone and ores. +tconstruct.manual.materialsandyou.tool.shovel=The Shovel is a precise digging tool. It is effective on dirt, sand, and snow. +tconstruct.manual.materialsandyou.tool.hatchet=The Hatchet is a basic chopping tool. It is effective on wood and leaves. +tconstruct.manual.materialsandyou.tool.mattock=The Cutter Mattock is a versatile farming tool. It is effective on wood, dirt, and plants.\n\nSpecial Ability: Hoe +tconstruct.manual.materialsandyou.tool.broadsword=The Broadsword is a defensive weapon. Blocking cuts damage in half.\n\nSpecial Ability: Block\nDamage: Moderate\nDurability: High +tconstruct.manual.materialsandyou.tool.longsword=The Longsword is an offensive weapon. It is often used for charging into battle at full speed.\n\nNatural Ability:\n- Charge Boost\nSpecial Ability: Lunge\n\nDamage: Moderate\nDurability: Moderate +tconstruct.manual.materialsandyou.tool.rapier=The Rapier is a special weapon that relies on quick strikes to defeat foes.\n\nNatural Abilities:\n- Armor Pierce\n- Quick Strike\n- Charge Boost\nSpecial Ability:\n- Backpedal\n\nDamage: Low\nDurability: Low +tconstruct.manual.materialsandyou.tool.dagger=The Dagger is a short blade that can be thrown.\n\nSpecial Ability:\n- Throw Item\n\nDamage: Low\nDurability: Moderate +tconstruct.manual.materialsandyou.tool.fryingpan=The Frying Pan is a heavy weapon that uses sheer weight to stun foes.\n\nSpecial Ability: Block\nNatural Ability: Heavy\nShift+rClick: Place Frying Pan\nDamage: Low\nDurability: High +tconstruct.manual.materialsandyou.tool.battlesign=The Battlesign is an advance in weapon technology worthy of Zombie Pigmen everywhere.\n\nSpecial Ability:\nDamage Reflector\n\nNatural Ability: Writable\n\nDamage: Low\nDurability: Average +tconstruct.manual.materialsandyou.tool.chisel=The Chisel is a utility tool that carves shapes into blocks.\n\nCrafting Grid:\n- Shape Items\nSpecial Ability: Chisel\nDurability: Average +tconstruct.manual.materialsandyou.tool.hammer=The Hammer is a broad mining tool. It harvests blocks in a wide range and is effective against undead.\n\nNatural Abilities:\nArea of Effect\n- (3x3)\n- Smite\n\nDurability: High +tconstruct.manual.materialsandyou.tool.lumberaxe=The Lumber Axe is a broad chopping tool. It can fell entire trees or gather wood in a wide range.\n\nNatural Abilities:\nArea of Effect\n- Fell Trees\n- (3x3x3)\n\nDurability: Average +tconstruct.manual.materialsandyou.tool.excavator=The Excavator is a broad digging tool. It harvests soil and snow in a wide range.\n\nNatural Ability:\n- Area of Effect\n- (3x3)\n\nDurability: Average +tconstruct.manual.materialsandyou.tool.scythe=The Scythe is a broad reaping tool. It is effective on plants and attacks enemies in a wide range.\n\nNatural Ability:\nArea of Effect\n- (3x3x3)\n\nDurability: Average\nDamage: Low, AoE +tconstruct.manual.materialsandyou.tool.cleaver=The Cleaver is a heavy defensive weapon. It has powerful strikes, but is difficult to wield.\n\nSpecial Ability: Block\nNatural Ability:\n- Beheading\n\nDamage: High\nDurability: Average +tconstruct.manual.materialsandyou.tool.battleaxe=The Battleaxe is a heavy offensive weapon. It is capable of bringing down small trees and can send foes flying.\n\nSpecial Ability: Block\nNatural Abilities:\n- Knockback\n- Area of Effect\n- (1x9)\n\nDamage: Average\nDurability: Average +tconstruct.manual.materialsandyou.tool.shortbow=The Shortbow is a ranged weapon. It fires arrows quickly and precisely at its foes.\n\nDraw Speed: quick +tconstruct.manual.materialsandyou.tool.longbow=The Longbow is a ranged weapon. It has greater range than a shortbow and is able to shoot heavier arrows, but performs worse with light arrows. +tconstruct.manual.materialsandyou.tool.arrowammo=Arrows are projectiles usually fired from bows. +tconstruct.manual.materialsandyou.tool.crossbow=The crossbow is a precise ranged weapon. It loads bolts, that are fired on trigger.\n\nSpecial Ability:\n- Reduced reload time with harder materials +tconstruct.manual.materialsandyou.tool.boltammo=Bolts are projectiles fired from Crossbows.\nBolt cores are obtained by pouring metal over a tool rod in a Casting Table. +tconstruct.manual.materialsandyou.tool.throwingknife=Mid ranged throwing weapon. Hold to take aim, release to throw.\n\nDamage: Medium\nCapacity: Medium +tconstruct.manual.materialsandyou.tool.shuriken=Short ranged throwing weapon. Thrown instantly.\n\nDamage: Low\nCapacity: High +tconstruct.manual.materialsandyou.tool.javelin=Ranged Melee weapon hybrid. Potent as a melee weapon, devastating at range.\n\nDamage: High\nCapacity: Low + + +tconstruct.manual.materialsandyou.recipetype.ShapedOreRecipe=Shaped Ore Recipe +tconstruct.manual.materialsandyou.recipetype.ShapelessOreRecipe=Shapeless Ore Recipe +tconstruct.manual.materialsandyou.recipetype.ShapedRecipes=Shaped Recipe +tconstruct.manual.materialsandyou.recipetype.ShapelessRecipes=Shapeless Recipe +tconstruct.manual.materialsandyou.recipetype.FurnaceRecipes=Furnace Recipe +tconstruct.manual.materialsandyou.recipetype.ToolStationRecipe=Tool Station +tconstruct.manual.materialsandyou.recipetype.ToolForgeRecipe=Tool Forge + + +tconstruct.manual.materialsandyou.navigation.tools=Tools + + diff --git a/src/main/resources/assets/tinker/lang/zh_CN.lang b/src/main/resources/assets/tinker/lang/zh_CN.lang index e129c93a601..58b397b56a6 100644 --- a/src/main/resources/assets/tinker/lang/zh_CN.lang +++ b/src/main/resources/assets/tinker/lang/zh_CN.lang @@ -1121,6 +1121,7 @@ modifier.tooltip.ThaumicSenses=神秘感知 modifier.tooltip.Triple-Jump=三重跳 modifier.tooltip.ThaumicVision=神秘视觉 modifier.tooltip.Water-Walking=水上行走 +modifier.tooltip.Auto-Repair=自动修复 option.tcon.searedtank=焦黑储罐 option.tcon.castingchannel=浇注道 diff --git a/src/main/resources/assets/tinker/manuals/materialsandyou.xml b/src/main/resources/assets/tinker/manuals/materialsandyou.xml new file mode 100644 index 00000000000..32cb907c774 --- /dev/null +++ b/src/main/resources/assets/tinker/manuals/materialsandyou.xml @@ -0,0 +1,158 @@ + + + + + tconstruct.manual.materialsandyou.homepage + + + + + + + + + + + + + tconstruct.manual.materialsandyou.welcome1 + + + + tconstruct.manual.materialsandyou.welcome2 + + + + TConstruct:blankPattern + + + + TConstruct:ToolStationBlock:10 + + + + TConstruct:ToolStationBlock:1 + + + + TConstruct:ToolStationBlock:5 + + + + TConstruct:ToolStationBlock + + + + TConstruct:ToolForgeBlock + + + + TConstruct:Armor.DryingRack + + + + tconstruct.manual.materialsandyou.oreberrydesc + + + + tconstruct.manual.materialsandyou.oreberrypic + tinker:manuals/oreberries.png + + + + tconstruct.manual.materialsandyou.slimechannels + + + + TConstruct:slime.channel + + + + TConstruct:slime.pad + + + + tconstruct.manual.materialsandyou.trap + + + + TConstruct:trap.punji + + + + TConstruct:trap.barricade.oak + + + + tconstruct.manual.materialsandyou.smelterydesc + + + + TConstruct:CraftedSoil:1 + + + + TConstruct:materials:2 + + + + TConstruct:Smeltery:2 + + + + TConstruct:Smeltery + + + + tconstruct.manual.materialsandyou.makenewbook + + + + minecraft:book + + + + TConstruct:manualBook + + + + TConstruct:manualBook:1 + + + + TConstruct:manualBook:2 + + + + TConstruct:manualBook:3 + + + + TConstruct:manualBook:4 + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/assets/tinker/textures/gui/bookleftbackground.png b/src/main/resources/assets/tinker/textures/gui/bookleftbackground.png new file mode 100644 index 00000000000..29ee3746ad5 Binary files /dev/null and b/src/main/resources/assets/tinker/textures/gui/bookleftbackground.png differ diff --git a/src/main/resources/assets/tinker/textures/gui/bookleftpage.png b/src/main/resources/assets/tinker/textures/gui/bookleftpage.png new file mode 100644 index 00000000000..f45184db52b Binary files /dev/null and b/src/main/resources/assets/tinker/textures/gui/bookleftpage.png differ diff --git a/src/main/resources/assets/tinker/textures/gui/bookmodifyandstation.png b/src/main/resources/assets/tinker/textures/gui/bookmodifyandstation.png new file mode 100644 index 00000000000..ac377484e3c Binary files /dev/null and b/src/main/resources/assets/tinker/textures/gui/bookmodifyandstation.png differ diff --git a/src/main/resources/assets/tinker/textures/gui/bookrightbackground.png b/src/main/resources/assets/tinker/textures/gui/bookrightbackground.png new file mode 100644 index 00000000000..0bfb7966c70 Binary files /dev/null and b/src/main/resources/assets/tinker/textures/gui/bookrightbackground.png differ diff --git a/src/main/resources/assets/tinker/textures/gui/bookrightpage.png b/src/main/resources/assets/tinker/textures/gui/bookrightpage.png new file mode 100644 index 00000000000..ddd470018e6 Binary files /dev/null and b/src/main/resources/assets/tinker/textures/gui/bookrightpage.png differ diff --git a/src/main/resources/assets/tinker/textures/items/tinkerbook_materialsandyou.png b/src/main/resources/assets/tinker/textures/items/tinkerbook_materialsandyou.png new file mode 100644 index 00000000000..69ee0324dbd Binary files /dev/null and b/src/main/resources/assets/tinker/textures/items/tinkerbook_materialsandyou.png differ