From f35a041a559cc998156363bb01f8b0b88b8e9b18 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Thu, 10 Nov 2016 19:50:01 +0100 Subject: [PATCH] Booklet rework, part 1. This is an API breaking change, by the way. --- .../api/ActuallyAdditionsAPI.java | 94 +-- .../api/booklet/BookletPage.java | 119 ---- .../api/booklet/IBookletChapter.java | 7 +- .../api/booklet/IBookletEntry.java | 5 +- .../api/booklet/IBookletPage.java | 30 + .../api/booklet/internal/IBookletGui.java | 18 + .../api/booklet/internal/IEntryGui.java | 20 + .../api/booklet/internal/IPageGui.java | 19 + .../api/internal/IBookletGui.java | 51 -- .../api/internal/IEntrySet.java | 43 -- .../api/internal/IMethodHandler.java | 15 - .../mod/ActuallyAdditions.java | 2 +- .../mod/blocks/BlockBookletStand.java | 165 ----- .../mod/blocks/InitBlocks.java | 2 - .../mod/booklet/BookletUtils.java | 614 ------------------ .../mod/booklet/GuiBooklet.java | 559 ---------------- .../mod/booklet/GuiBookletStand.java | 82 --- .../mod/booklet/InitBooklet.java | 27 +- .../mod/booklet/button/BookmarkButton.java | 103 --- .../{IndexButton.java => EntryButton.java} | 33 +- .../mod/booklet/chapter/BookletChapter.java | 42 +- .../booklet/chapter/BookletChapterCoffee.java | 45 -- .../chapter/BookletChapterCrusher.java | 39 -- .../mod/booklet/entry/BookletEntry.java | 8 +- ...lSearch.java => BookletEntryAllItems.java} | 9 +- .../mod/booklet/entry/EntrySet.java | 125 ---- .../mod/booklet/gui/GuiBooklet.java | 87 +++ .../mod/booklet/gui/GuiEntry.java | 48 ++ .../mod/booklet/gui/GuiMainPage.java | 41 ++ .../mod/booklet/gui/GuiPage.java | 30 + .../mod/booklet/misc/BookletUtils.java | 33 + .../booklet/{ => misc}/GuiAAAchievements.java | 5 +- .../{BookletPageAA.java => BookletPage.java} | 75 ++- .../mod/booklet/page/PageButton.java | 46 -- .../mod/booklet/page/PageCoffeeRecipe.java | 109 ---- .../mod/booklet/page/PageCrafting.java | 201 ------ .../mod/booklet/page/PageCrusherRecipe.java | 108 --- .../mod/booklet/page/PageEmpowerer.java | 152 ----- .../mod/booklet/page/PageFurnace.java | 107 --- .../mod/booklet/page/PageLinkButton.java | 29 - .../mod/booklet/page/PagePicture.java | 50 -- .../mod/booklet/page/PageReconstructor.java | 122 ---- .../mod/booklet/page/PageTextOnly.java | 46 -- .../mod/creative/CreativeTab.java | 1 - .../mod/inventory/GuiHandler.java | 9 +- .../gui}/TexturedButton.java | 14 +- .../mod/items/ItemBooklet.java | 22 +- .../mod/jei/RecipeWrapperWithButton.java | 19 +- .../mod/jei/booklet/BookletRecipeHandler.java | 12 +- .../mod/jei/booklet/BookletRecipeWrapper.java | 13 +- .../coffee/CoffeeMachineRecipeWrapper.java | 8 +- .../mod/jei/crusher/CrusherRecipeWrapper.java | 10 +- .../jei/empowerer/EmpowererRecipeWrapper.java | 13 +- .../ReconstructorRecipeWrapper.java | 13 +- .../mod/misc/MethodHandler.java | 33 - .../mod/network/PacketHandler.java | 19 - .../mod/proxy/ClientProxy.java | 15 +- .../mod/tile/TileEntityBase.java | 1 - .../mod/tile/TileEntityBookletStand.java | 47 -- .../mod/util/StringUtil.java | 23 + .../textures/gui/booklet/guiBooklet.png | Bin 16670 -> 25178 bytes .../textures/gui/booklet/guiBookletAddon.png | Bin 1895 -> 0 bytes .../gui/booklet/guiBookletGadgets.png | Bin 0 -> 2384 bytes .../textures/gui/booklet/ra.png | Bin 34841 -> 0 bytes 64 files changed, 531 insertions(+), 3306 deletions(-) delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/booklet/BookletPage.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IBookletGui.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IEntryGui.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IPageGui.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/internal/IBookletGui.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/internal/IEntrySet.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/blocks/BlockBookletStand.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/BookletUtils.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBooklet.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBookletStand.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/BookmarkButton.java rename src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/{IndexButton.java => EntryButton.java} (56%) delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCoffee.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCrusher.java rename src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/{BookletEntryAllSearch.java => BookletEntryAllItems.java} (56%) delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/EntrySet.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiBooklet.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiEntry.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiMainPage.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiPage.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/misc/BookletUtils.java rename src/main/java/de/ellpeck/actuallyadditions/mod/booklet/{ => misc}/GuiAAAchievements.java (88%) rename src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/{BookletPageAA.java => BookletPage.java} (64%) delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageButton.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeRecipe.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrafting.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrusherRecipe.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageEmpowerer.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageFurnace.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageLinkButton.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PagePicture.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageReconstructor.java delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTextOnly.java rename src/main/java/de/ellpeck/actuallyadditions/mod/{booklet/button => inventory/gui}/TexturedButton.java (75%) delete mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBookletStand.java delete mode 100644 src/main/resources/assets/actuallyadditions/textures/gui/booklet/guiBookletAddon.png create mode 100644 src/main/resources/assets/actuallyadditions/textures/gui/booklet/guiBookletGadgets.png delete mode 100644 src/main/resources/assets/actuallyadditions/textures/gui/booklet/ra.png diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java b/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java index 095b4dbb7..f06cccdb3 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java @@ -10,9 +10,9 @@ package de.ellpeck.actuallyadditions.api; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.api.internal.IMethodHandler; import de.ellpeck.actuallyadditions.api.laser.ILaserRelayConnectionHandler; import de.ellpeck.actuallyadditions.api.lens.Lens; @@ -31,7 +31,7 @@ public final class ActuallyAdditionsAPI{ public static final String MOD_ID = "actuallyadditions"; public static final String API_ID = MOD_ID+"api"; - public static final String API_VERSION = "26"; + public static final String API_VERSION = "27"; public static final List CRUSHER_RECIPES = new ArrayList(); public static final List BALL_OF_FUR_RETURN_ITEMS = new ArrayList(); @@ -46,7 +46,7 @@ public final class ActuallyAdditionsAPI{ //This is added to automatically, you don't need to add anything to this list public static final List ALL_CHAPTERS = new ArrayList(); //This is added to automatically, you don't need to add anything to this list - public static final List BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA = new ArrayList(); + public static final List BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA = new ArrayList(); public static final List STONE_ORES = new ArrayList(); public static final List NETHERRACK_ORES = new ArrayList(); @@ -90,66 +90,6 @@ public final class ActuallyAdditionsAPI{ public static Lens lensDisenchanting; public static Lens lensMining; - /** - * Adds a Recipe to the Crusher Recipe Registry - * The second output will be nothing - * - * @param input The input's OreDictionary name - * @param outputOne The first output's OreDictionary name - * @param outputOneAmount The amount of the first output - */ - @Deprecated //Use new version below - public static void addCrusherRecipe(String input, String outputOne, int outputOneAmount){ - } - - /** - * Adds a Recipe to the Crusher Recipe Registry - * - * @param input The input's OreDictionary name - * @param outputOne The first output's OreDictionary name - * @param outputOneAmount The amount of the first output - * @param outputTwo The second output's OreDictionary name - * @param outputTwoAmount The amount of the second output - * @param outputTwoChance The chance of the second output (0 won't occur at all, 100 will all the time) - */ - @Deprecated //Use new version below - public static void addCrusherRecipe(String input, String outputOne, int outputOneAmount, String outputTwo, int outputTwoAmount, int outputTwoChance){ - } - - /** - * Adds a Recipe to the Crusher Recipe Registry - * The second output will be nothing - * - * @param input The input as an ItemStack - * @param outputOne The first output as an ItemStack - */ - @Deprecated //Use new version below - public static void addCrusherRecipe(ItemStack input, ItemStack outputOne){ - } - - /** - * Adds a Recipe to the Crusher Recipe Registry - * The second output will be nothing - * - * @param input The input as an ItemStack - * @param outputOne The first output's OreDictionary name - * @param outputOneAmount The amount of the first output - */ - @Deprecated //Use new version below - public static void addCrusherRecipe(ItemStack input, String outputOne, int outputOneAmount){ - } - - /** - * Adds a Recipe to the Crusher Recipe Registry - * The second output will be nothing - * - * @param input The input as an ItemStack - * @param outputOne The first output's OreDictionary name - */ - @Deprecated //Use new version below - public static void addCrusherRecipe(String input, ItemStack outputOne){ - } - /** * Adds an ore with a specific weight to the list of ores that the lens of the miner will generate inside of stone. * Higher weight means higher occurence. @@ -266,23 +206,6 @@ public final class ActuallyAdditionsAPI{ addReconstructorLensConversionRecipe(input, output, energyUse, lensDefaultConversion); } - /** - * Adds a recipe to the Atomic Reconstructor conversion lenses - * - * @param input The input's OreDictionary name - * @param output The output's OreDictionary name - * @param energyUse The amount of RF used per conversion - * @param type The type of lens used for the conversion. To use the default type, use method below - * Note how this always has to be the same instance of the lens type that the item also has for it to work! - */ - @Deprecated //Use ItemStack recipes - public static void addReconstructorLensConversionRecipe(String input, String output, int energyUse, LensConversion type){ - } - - @Deprecated //Use ItemStack recipes - public static void addReconstructorLensConversionRecipe(String input, String output, int energyUse){ - } - /** * Adds an item and the way it is modified to the Atomic Reconstructor's color lens. * This also works for blocks, but they have to be in their item form. @@ -313,15 +236,4 @@ public final class ActuallyAdditionsAPI{ public static void addBookletEntry(IBookletEntry entry){ BOOKLET_ENTRIES.add(entry); } - - /** - * Adds a page to the pages with ItemStack data - * This should be done with every page that uses getItemStacksForPage() - * - * @param page The page to add - */ - @Deprecated //Search will now be done on all pages that are in the book - public static void addPageWithItemStackData(BookletPage page){ - BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA.add(page); - } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/BookletPage.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/BookletPage.java deleted file mode 100644 index 521644355..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/BookletPage.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file ("BookletPage.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.api.booklet; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.HashMap; - -public abstract class BookletPage{ - - protected final HashMap textReplacements = new HashMap(); - public boolean arePageStacksWildcard; - protected IBookletChapter chapter; - protected boolean hasNoText; - - public void onOpened(IBookletGui gui){ - - } - - public void onClosed(IBookletGui gui){ - - } - - public boolean onActionPerformed(IBookletGui gui, GuiButton button){ - return false; - } - - /** - * The ID of the page, for the page number etc. - * Don't make two pages in the same chapter with the same ID. - */ - public abstract int getID(); - - /** - * Gets the localized text to be displayed - */ - public abstract String getText(); - - /** - * This render method ica called before super.drawScreen() is called in the GUI - */ - @SideOnly(Side.CLIENT) - public abstract void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed); - - /** - * This render method ica called after super.drawScreen() is called in the GUI - */ - @SideOnly(Side.CLIENT) - public abstract void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed); - - /** - * Equivalent to updateScreen() in GuiScreen - */ - @SideOnly(Side.CLIENT) - public abstract void updateScreen(int ticksElapsed); - - /** - * Gets the ItemStacks that are part of or displayed on this page (for JEI Handler and search) - */ - public ItemStack[] getItemStacksForPage(){ - return new ItemStack[0]; - } - - /** - * Gets the FluidStacks that are part of or displayed on this page (for JEI Handler and search) - */ - public FluidStack[] getFluidStacksForPage(){ - return new FluidStack[0]; - } - - /** - * Gets the text that is displayed when an Item is hovered over that can be clicked on to go to its page - */ - public abstract String getClickToSeeRecipeString(); - - public IBookletChapter getChapter(){ - return this.chapter; - } - - public void setChapter(IBookletChapter chapter){ - this.chapter = chapter; - } - - /** - * Sets the stacks on the page to be wildcard, meaning the metadata doesn't matter - * This applies for all stacks at once - */ - public BookletPage setPageStacksWildcard(){ - this.arePageStacksWildcard = true; - return this; - } - - public BookletPage setNoText(){ - this.hasNoText = true; - return this; - } - - public BookletPage addTextReplacement(String text, int replacement){ - return this.addTextReplacement(text, Integer.toString(replacement)); - } - - public BookletPage addTextReplacement(String text, String replacement){ - this.textReplacements.put(text, replacement); - return this; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletChapter.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletChapter.java index e702f4ffb..76d798c39 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletChapter.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletChapter.java @@ -14,11 +14,7 @@ import net.minecraft.item.ItemStack; public interface IBookletChapter{ - BookletPage[] getPages(); - - BookletPage getPageById(int id); - - int getPageId(BookletPage page); + IBookletPage[] getAllPages(); String getLocalizedName(); @@ -30,4 +26,5 @@ public interface IBookletChapter{ String getIdentifier(); + int getPageNum(IBookletPage page); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletEntry.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletEntry.java index c8695e18b..675edc937 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletEntry.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletEntry.java @@ -10,11 +10,13 @@ package de.ellpeck.actuallyadditions.api.booklet; +import de.ellpeck.actuallyadditions.api.booklet.internal.IEntryGui; + import java.util.List; public interface IBookletEntry{ - List getChapters(); + List getAllChapters(); void setChapters(List chapters); @@ -26,4 +28,5 @@ public interface IBookletEntry{ void addChapter(IBookletChapter chapter); + IEntryGui createGui(); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java new file mode 100644 index 000000000..1af764db3 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java @@ -0,0 +1,30 @@ +/* + * This file ("BookletPage.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.api.booklet; + +import de.ellpeck.actuallyadditions.api.booklet.internal.IPageGui; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +public interface IBookletPage{ + + ItemStack[] getItemStacksForPage(); + + FluidStack[] getFluidStacksForPage(); + + IBookletChapter getChapter(); + + void setChapter(IBookletChapter chapter); + + IPageGui createGui(); + + String getInfoText(); +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IBookletGui.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IBookletGui.java new file mode 100644 index 000000000..bff350736 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IBookletGui.java @@ -0,0 +1,18 @@ +/* + * This file ("IBookGui.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.api.booklet.internal; + +public interface IBookletGui{ + + void renderScaledAsciiString(String text, int x, int y, int color, boolean shadow, float scale); + + void renderSplitScaledAsciiString(String text, int x, int y, int color, boolean shadow, float scale, int length); +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IEntryGui.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IEntryGui.java new file mode 100644 index 000000000..97bbb813e --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IEntryGui.java @@ -0,0 +1,20 @@ +/* + * This file ("IEntryGui.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.api.booklet.internal; + +import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; + +public interface IEntryGui extends IBookletGui{ + + IBookletEntry getEntry(); + + int getEntryPage(); +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IPageGui.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IPageGui.java new file mode 100644 index 000000000..0dbca2290 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/internal/IPageGui.java @@ -0,0 +1,19 @@ +/* + * This file ("IPageGui.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.api.booklet.internal; + +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; + +public interface IPageGui extends IBookletGui{ + + IBookletPage getPage(); + +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/internal/IBookletGui.java b/src/main/java/de/ellpeck/actuallyadditions/api/internal/IBookletGui.java deleted file mode 100644 index ca92ace10..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/api/internal/IBookletGui.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file ("IBookletGui.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.api.internal; - -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.List; - -/** - * This is a helper interface for BookletPage - * This is not supposed to be implemented. - *

- * Can be cast to GuiScreen. - */ -public interface IBookletGui{ - - /** - * This method should be used when drawing an ItemStack to a booklet page - * It displays the hoverover text of the item and also contains the "show more info"-text and clickable part - * - * @param renderTransferButton if the "show more info"-text and clickable part should exist - */ - @SideOnly(Side.CLIENT) - void renderTooltipAndTransferButton(BookletPage from, ItemStack stack, int x, int y, boolean renderTransferButton, boolean mousePressed); - - int getXSize(); - - int getYSize(); - - int getGuiLeft(); - - int getGuiTop(); - - void drawRect(int startX, int startY, int u, int v, int xSize, int ySize); - - IEntrySet getCurrentEntrySet(); - - List getButtonList(); -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/internal/IEntrySet.java b/src/main/java/de/ellpeck/actuallyadditions/api/internal/IEntrySet.java deleted file mode 100644 index 7509001b2..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/api/internal/IEntrySet.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file ("IEntrySet.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.api.internal; - -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; -import net.minecraft.nbt.NBTTagCompound; - -public interface IEntrySet{ - - void setEntry(BookletPage page, IBookletChapter chapter, IBookletEntry entry, int pageInIndex); - - void removeEntry(); - - void writeToNBT(NBTTagCompound compound); - - void readFromNBT(NBTTagCompound compound); - - BookletPage getCurrentPage(); - - IBookletEntry getCurrentEntry(); - - IBookletChapter getCurrentChapter(); - - int getPageInIndex(); - - void setPage(BookletPage page); - - void setEntry(IBookletEntry entry); - - void setChapter(IBookletChapter chapter); - - void setPageInIndex(int page); -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/internal/IMethodHandler.java b/src/main/java/de/ellpeck/actuallyadditions/api/internal/IMethodHandler.java index ac3640131..bc799af65 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/internal/IMethodHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/internal/IMethodHandler.java @@ -10,15 +10,10 @@ package de.ellpeck.actuallyadditions.api.internal; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; import de.ellpeck.actuallyadditions.api.recipe.CoffeeIngredient; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.IRecipe; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import java.util.List; @@ -42,15 +37,5 @@ public interface IMethodHandler{ boolean invokeConversionLens(IBlockState hitState, BlockPos hitBlock, IAtomicReconstructor tile); - BookletPage generateTextPage(int id); - - BookletPage generatePicturePage(int id, ResourceLocation resLoc, int textStartY); - - BookletPage generateCraftingPage(int id, IRecipe... recipes); - - BookletPage generateFurnacePage(int id, ItemStack input, ItemStack result); - - IBookletChapter generateBookletChapter(String identifier, IBookletEntry entry, ItemStack displayStack, BookletPage... pages); - boolean addCrusherRecipes(List inputs, List outputOnes, int outputOneAmounts, List outputTwos, int outputTwoAmounts, int outputTwoChance); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java index 008344e07..af73247df 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java @@ -150,7 +150,7 @@ public class ActuallyAdditions{ if(mapping.name != null){ String name = mapping.name.toLowerCase(Locale.ROOT); if(name.startsWith(ModUtil.MOD_ID+":")){ - if(name.contains("paxel") || name.contains("itemspecial") || name.contains("blockbookstand") || name.contains("rarmor") || name.contains("bucket") || name.contains("modulereconstructor")){ + if(name.contains("paxel") || name.contains("itemspecial") || name.contains("blockbookstand") || name.contains("rarmor") || name.contains("bucket") || name.contains("modulereconstructor") || name.contains("stand")){ mapping.ignore(); ModUtil.LOGGER.info("Missing Mapping "+mapping.name+" is getting ignored. This is intentional."); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/BlockBookletStand.java b/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/BlockBookletStand.java deleted file mode 100644 index 039600059..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/BlockBookletStand.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file ("BlockBookletStand.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.blocks; - -import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; -import de.ellpeck.actuallyadditions.mod.blocks.base.BlockContainerBase; -import de.ellpeck.actuallyadditions.mod.booklet.entry.EntrySet; -import de.ellpeck.actuallyadditions.mod.inventory.GuiHandler; -import de.ellpeck.actuallyadditions.mod.items.InitItems; -import de.ellpeck.actuallyadditions.mod.tile.TileEntityBookletStand; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import net.minecraft.block.SoundType; -import net.minecraft.block.material.Material; -import net.minecraft.block.properties.PropertyInteger; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumRarity; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextFormatting; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public class BlockBookletStand extends BlockContainerBase implements IHudDisplay{ - - private static final PropertyInteger META = PropertyInteger.create("meta", 0, 3); - - private static final AxisAlignedBB AABB_1 = new AxisAlignedBB(0, 3*0.0625, 0, 1, 14*0.0625, 0.0625); - private static final AxisAlignedBB AABB_2 = new AxisAlignedBB(0, 3*0.0625, 0, 0.0625, 14*0.0625, 1); - private static final AxisAlignedBB AABB_3 = new AxisAlignedBB(1-0.0625, 3*0.0625, 0, 1, 14*0.0625, 1); - private static final AxisAlignedBB AABB_4 = new AxisAlignedBB(1, 3*0.0625, 1-0.0625, 0, 14*0.0625, 1); - - public BlockBookletStand(String name){ - super(Material.WOOD, name); - this.setHarvestLevel("axe", 0); - this.setHardness(1.0F); - this.setResistance(4.0F); - this.setSoundType(SoundType.WOOD); - } - - @Override - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ - int meta = this.getMetaFromState(state); - switch(meta){ - case 0: - return AABB_4; - case 1: - return AABB_1; - case 2: - return AABB_3; - case 3: - return AABB_2; - } - return super.getBoundingBox(state, source, pos); - } - - @Override - public boolean isFullCube(IBlockState state){ - return false; - } - - @Override - public boolean isOpaqueCube(IBlockState state){ - return false; - } - - @Override - public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack stack, EnumFacing par6, float par7, float par8, float par9){ - player.openGui(ActuallyAdditions.instance, GuiHandler.GuiTypes.BOOK_STAND.ordinal(), world, pos.getX(), pos.getY(), pos.getZ()); - return true; - } - - @Override - public EnumRarity getRarity(ItemStack stack){ - return EnumRarity.RARE; - } - - @Override - public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack){ - int rotation = MathHelper.floor_double((double)(player.rotationYaw*4.0F/360.0F)+0.5D) & 3; - - if(rotation == 0){ - world.setBlockState(pos, this.getStateFromMeta(0), 2); - } - if(rotation == 1){ - world.setBlockState(pos, this.getStateFromMeta(3), 2); - } - if(rotation == 2){ - world.setBlockState(pos, this.getStateFromMeta(1), 2); - } - if(rotation == 3){ - world.setBlockState(pos, this.getStateFromMeta(2), 2); - } - - TileEntityBookletStand tile = (TileEntityBookletStand)world.getTileEntity(pos); - if(tile != null){ - if(tile.assignedPlayer == null){ - tile.assignedPlayer = player.getName(); - tile.markDirty(); - tile.sendUpdate(); - } - } - - super.onBlockPlacedBy(world, pos, state, player, stack); - } - - - @Override - public TileEntity createNewTileEntity(World world, int par2){ - return new TileEntityBookletStand(); - } - - @Override - @SideOnly(Side.CLIENT) - public void displayHud(Minecraft minecraft, EntityPlayer player, ItemStack stack, RayTraceResult posHit, ScaledResolution resolution){ - TileEntity tile = minecraft.theWorld.getTileEntity(posHit.getBlockPos()); - if(tile instanceof TileEntityBookletStand){ - EntrySet set = ((TileEntityBookletStand)tile).assignedEntry; - - String strg1; - String strg2; - if(set.getCurrentEntry() == null){ - strg1 = "No entry saved! Save one if"; - strg2 = "you are the player who placed it!"; - } - else if(set.getCurrentChapter() == null){ - strg1 = set.getCurrentEntry().getLocalizedName(); - strg2 = "Page "+set.getPageInIndex(); - } - else{ - strg1 = set.getCurrentChapter().getLocalizedName(); - strg2 = "Page "+set.getCurrentPage().getID(); - - AssetUtil.renderStackToGui(set.getCurrentChapter().getDisplayItemStack() != null ? set.getCurrentChapter().getDisplayItemStack() : new ItemStack(InitItems.itemBooklet), resolution.getScaledWidth()/2+5, resolution.getScaledHeight()/2+10, 1F); - } - minecraft.fontRendererObj.drawStringWithShadow(TextFormatting.YELLOW+""+TextFormatting.ITALIC+strg1, resolution.getScaledWidth()/2+25, resolution.getScaledHeight()/2+8, StringUtil.DECIMAL_COLOR_WHITE); - minecraft.fontRendererObj.drawStringWithShadow(TextFormatting.YELLOW+""+TextFormatting.ITALIC+strg2, resolution.getScaledWidth()/2+25, resolution.getScaledHeight()/2+18, StringUtil.DECIMAL_COLOR_WHITE); - } - } - - @Override - protected PropertyInteger getMetaProperty(){ - return META; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java b/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java index 00cf5e444..55ffa4519 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java @@ -101,7 +101,6 @@ public final class InitBlocks{ public static Block blockPillarQuartzWall; public static Block blockPillarQuartzStair; public static Block blockPillarQuartzSlab; - public static Block blockBookletStand; public static Block blockDisplayStand; public static Block blockShockSuppressor; public static Block blockEmpowerer; @@ -121,7 +120,6 @@ public final class InitBlocks{ blockShockSuppressor = new BlockShockSuppressor("blockShockSuppressor"); blockDisplayStand = new BlockDisplayStand("blockDisplayStand"); blockPlayerInterface = new BlockPlayerInterface("blockPlayerInterface"); - blockBookletStand = new BlockBookletStand("blockBookletStand"); blockItemViewer = new BlockItemViewer("blockItemViewer"); blockFireworkBox = new BlockFireworkBox("blockFireworkBox"); blockMiner = new BlockMiner("blockMiner"); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/BookletUtils.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/BookletUtils.java deleted file mode 100644 index 38fb57ac8..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/BookletUtils.java +++ /dev/null @@ -1,614 +0,0 @@ -/* - * This file ("BookletUtils.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet; - -import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; -import de.ellpeck.actuallyadditions.mod.achievement.TheAchievements; -import de.ellpeck.actuallyadditions.mod.booklet.button.BookmarkButton; -import de.ellpeck.actuallyadditions.mod.booklet.button.IndexButton; -import de.ellpeck.actuallyadditions.mod.booklet.button.TexturedButton; -import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntryAllSearch; -import de.ellpeck.actuallyadditions.mod.booklet.entry.EntrySet; -import de.ellpeck.actuallyadditions.mod.proxy.ClientProxy; -import de.ellpeck.actuallyadditions.mod.util.ItemUtil; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import de.ellpeck.actuallyadditions.mod.util.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.apache.commons.lang3.ArrayUtils; - -import java.awt.*; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -public final class BookletUtils{ - - /** - * Tries to open a URL in the Browser - */ - @SideOnly(Side.CLIENT) - public static void openBrowser(String url){ - openBrowser(url, url); - } - - /** - * Tries to open a URL in the Browser - * - * @param url The URL - * @param shiftUrl The URL to open when Shift is held - */ - @SideOnly(Side.CLIENT) - public static void openBrowser(String url, String shiftUrl){ - try{ - if(Desktop.isDesktopSupported()){ - if(shiftUrl.equals(url) || GuiScreen.isShiftKeyDown()){ - Desktop.getDesktop().browse(new URI(shiftUrl)); - } - else{ - Desktop.getDesktop().browse(new URI(url)); - } - } - } - catch(Exception e){ - ModUtil.LOGGER.error("Something bad happened when trying to open a URL!", e); - } - } - - /** - * Draws the Title of the current chapter, current index entry or just "Actually Additions" if neither is present - */ - @SideOnly(Side.CLIENT) - public static void drawTitle(GuiBooklet booklet){ - booklet.mc.getTextureManager().bindTexture(GuiBooklet.RES_LOC); - //Upper title - booklet.drawTexturedModalRect(booklet.guiLeft+booklet.xSize/2-142/2, booklet.guiTop-12, 0, 240, 142, 12); - //Lower title - booklet.drawTexturedModalRect(booklet.guiLeft+booklet.xSize/2-142/2, booklet.guiTop+booklet.ySize, 0, 243, 142, 13); - - //Draw No Entry title - if(booklet.currentEntrySet.getCurrentEntry() == null){ - String strg = TextFormatting.DARK_GREEN+StringUtil.localize(booklet.bookletName); - booklet.getFontRenderer().drawString(strg, booklet.guiLeft+booklet.xSize/2-booklet.getFontRenderer().getStringWidth(strg)/2-3, booklet.guiTop+12, 0); - strg = TextFormatting.DARK_GREEN+StringUtil.localize("info."+ModUtil.MOD_ID+".booklet.manualName.2"); - booklet.getFontRenderer().drawString(strg, booklet.guiLeft+booklet.xSize/2-booklet.getFontRenderer().getStringWidth(strg)/2-3, booklet.guiTop+12+booklet.getFontRenderer().FONT_HEIGHT, 0); - - String versionStrg; - String playerName = Minecraft.getMinecraft().thePlayer.getName(); - - if(Util.isDevVersion()){ - versionStrg = "Dev's Edition"; - } - else{ - String modVersion = Util.getMajorModVersion(); - if(playerName.equalsIgnoreCase("dqmhose")){ - versionStrg = "Pants Edition"; - } - else if(playerName.equalsIgnoreCase("TwoOfEight") || playerName.equalsIgnoreCase("BootyToast")){ - versionStrg = "Illustrator's Edition"; - } - else if(playerName.equalsIgnoreCase("KittyVanCat")){ - versionStrg = "Cat's Edition"; - } - else if(playerName.equalsIgnoreCase("canitzp")){ - versionStrg = "P's Edition"; - } - else if(playerName.equalsIgnoreCase("Ellpeck")){ - versionStrg = "Dev's Edition"; - } - else if(playerName.equalsIgnoreCase("direwolf20")){ - versionStrg = "Edition 20"; - } - else if(playerName.equalsIgnoreCase("dannydjdk") || playerName.equalsIgnoreCase("andrew_period")){ - versionStrg = "Derp's Edition"; - } - else if(playerName.equalsIgnoreCase("mezz")){ - versionStrg = "Just Enough Edition"; - } - else{ - versionStrg = StringUtil.localize("info."+ModUtil.MOD_ID+".booklet.edition")+" "+modVersion; - } - } - - strg = TextFormatting.GOLD+TextFormatting.ITALIC.toString()+"-"+versionStrg+"-"; - booklet.getFontRenderer().drawString(strg, booklet.guiLeft+booklet.xSize/2-booklet.getFontRenderer().getStringWidth(strg)/2-3, booklet.guiTop+33, 0); - } - - String strg = booklet.currentEntrySet.getCurrentChapter() == null ? (booklet.currentEntrySet.getCurrentEntry() == null ? StringUtil.localize("itemGroup."+ModUtil.MOD_ID) : booklet.currentEntrySet.getCurrentEntry().getLocalizedName()) : booklet.currentEntrySet.getCurrentChapter().getLocalizedName(); - booklet.drawCenteredString(booklet.getFontRenderer(), strg, booklet.guiLeft+booklet.xSize/2, booklet.guiTop-9, StringUtil.DECIMAL_COLOR_WHITE); - } - - /** - * Draws an Achievement Info if the page has items that trigger achievements - * - * @param pre If the hover info texts or the icon should be drawn - */ - @SideOnly(Side.CLIENT) - public static void drawAchievementInfo(GuiBooklet booklet, boolean pre, int mouseX, int mouseY){ - if(booklet.currentEntrySet.getCurrentChapter() == null){ - return; - } - - List achievements = null; - for(BookletPage page : booklet.currentEntrySet.getCurrentChapter().getPages()){ - ItemStack[] stacks = page.getItemStacksForPage(); - if(page != null && stacks != null){ - for(ItemStack stack : stacks){ - if(stack != null){ - for(TheAchievements achievement : TheAchievements.values()){ - if(ItemUtil.contains(achievement.itemsToBeGotten, stack, true)){ - if(pre){ - booklet.mc.getTextureManager().bindTexture(GuiBooklet.RES_LOC); - booklet.drawTexturedModalRect(booklet.guiLeft+booklet.xSize+1, booklet.guiTop-18, 166, 154, 22, 21); - return; - } - else{ - if(mouseX >= booklet.guiLeft+booklet.xSize+1 && mouseX < booklet.guiLeft+booklet.xSize+1+22 && mouseY >= booklet.guiTop-18 && mouseY < booklet.guiTop-18+21){ - if(achievements == null){ - achievements = new ArrayList(); - } - if(!achievements.contains(achievement)){ - achievements.add(achievement); - } - } - } - } - } - } - } - } - } - - if(achievements != null){ - List infoList = null; - for(TheAchievements achievement : achievements){ - if(infoList == null){ - infoList = new ArrayList(); - infoList.add(TextFormatting.GOLD+"Achievements related to this chapter:"); - } - infoList.add("-"+StringUtil.localize(achievement.chieve.statId)); - infoList.add(TextFormatting.GRAY+"("+achievement.chieve.getDescription()+")"); - } - - if(infoList != null){ - booklet.drawHoveringText(infoList, mouseX, mouseY); - } - } - } - - /** - * Pre-renders the booklet page, including - * -the number of a page and its content (text, crafting recipe etc.) - * -the number of a page in a chapter - * -the amount of words and chars in the index (Just for teh lulz) - */ - @SideOnly(Side.CLIENT) - public static void renderPre(GuiBooklet booklet, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - if(booklet.currentEntrySet.getCurrentEntry() != null){ - //Renders Booklet Page Number and Content - if(booklet.currentEntrySet.getCurrentChapter() != null && booklet.currentEntrySet.getCurrentPage() != null){ - booklet.drawCenteredString(booklet.getFontRenderer(), booklet.currentEntrySet.getCurrentPage().getID()+"/"+booklet.currentEntrySet.getCurrentChapter().getPages().length, booklet.guiLeft+booklet.xSize/2, booklet.guiTop+171, StringUtil.DECIMAL_COLOR_WHITE); - booklet.currentEntrySet.getCurrentPage().renderPre(booklet, mouseX, mouseY, ticksElapsed, mousePressed); - } - //Renders Chapter Page Number - else{ - booklet.drawCenteredString(booklet.getFontRenderer(), booklet.currentEntrySet.getPageInIndex()+"/"+booklet.indexPageAmount, booklet.guiLeft+booklet.xSize/2, booklet.guiTop+171, StringUtil.DECIMAL_COLOR_WHITE); - } - } - //Renders the amount of words and chars the book has - else{ - String countStrg = StringUtil.localizeFormatted("booklet."+ModUtil.MOD_ID+".amountOfWordsAndChars", ClientProxy.bookletWordCount, ClientProxy.bookletCharCount); - booklet.getFontRenderer().drawString(TextFormatting.ITALIC+countStrg, booklet.guiLeft+booklet.xSize/2-booklet.getFontRenderer().getStringWidth(countStrg)/2, booklet.guiTop+booklet.ySize+1, 0); - } - } - - /** - * Draws all of the hovering texts for the buttons that need explanation in the booklet - */ - @SideOnly(Side.CLIENT) - public static void doHoverTexts(GuiBooklet booklet, int mouseX, int mouseY){ - //Update all of the buttons' hovering texts - for(Object button : booklet.getButtonList()){ - if(button instanceof GuiButton && ((GuiButton)button).visible && ((GuiButton)button).isMouseOver()){ - if(button instanceof BookmarkButton){ - ((BookmarkButton)button).drawHover(mouseX, mouseY); - } - else if(button instanceof TexturedButton){ - booklet.drawHoveringText(((TexturedButton)button).textList, mouseX, mouseY); - } - } - } - } - - /** - * Updates the search bar, should be called when it is getting typed into - */ - @SideOnly(Side.CLIENT) - public static void updateSearchBar(GuiBooklet booklet){ - boolean change = false; - - IBookletEntry current = booklet.currentEntrySet.getCurrentEntry(); - boolean isAllSearch = current instanceof BookletEntryAllSearch; - - if(booklet.searchField.getText() != null && !booklet.searchField.getText().isEmpty()){ - if(!isAllSearch){ - openIndexEntry(booklet, ActuallyAdditionsAPI.allAndSearch, 1, false); - current = booklet.currentEntrySet.getCurrentEntry(); - } - - current.getChapters().clear(); - for(IBookletChapter chapter : ActuallyAdditionsAPI.ALL_CHAPTERS){ - String searchFieldText = booklet.searchField.getText().toLowerCase(Locale.ROOT); - if(chapter.getLocalizedName().toLowerCase(Locale.ROOT).contains(searchFieldText) || getChapterStacksContainString(searchFieldText, chapter)){ - current.getChapters().add(chapter); - } - } - - change = true; - } - else if(isAllSearch){ - current.setChapters(ActuallyAdditionsAPI.ALL_CHAPTERS); - change = true; - } - - if(change){ - openIndexEntry(booklet, current, booklet.currentEntrySet.getPageInIndex(), false); - } - } - - @SideOnly(Side.CLIENT) - private static boolean getChapterStacksContainString(String text, IBookletChapter chapter){ - Minecraft mc = Minecraft.getMinecraft(); - for(BookletPage page : chapter.getPages()){ - ItemStack[] pageStacks = page.getItemStacksForPage(); - if(pageStacks != null){ - for(ItemStack stack : pageStacks){ - if(stack != null && stack.getItem() != null){ - if(doesTooltipContainString(stack.getTooltip(mc.thePlayer, mc.gameSettings.advancedItemTooltips), text)){ - return true; - } - } - } - } - FluidStack[] pageFluids = page.getFluidStacksForPage(); - if(pageFluids != null){ - for(FluidStack stack : pageFluids){ - if(stack != null && stack.getFluid() != null){ - if(doesTooltipContainString(Collections.singletonList(stack.getLocalizedName()), text)){ - return true; - } - } - } - } - } - return false; - } - - @SideOnly(Side.CLIENT) - private static boolean doesTooltipContainString(List tooltip, String text){ - for(String s : tooltip){ - if(s != null && !s.isEmpty()){ - if(s.toLowerCase(Locale.ROOT).contains(text)){ - return true; - } - } - } - return false; - } - - @SideOnly(Side.CLIENT) - public static void openIndexEntry(GuiBooklet booklet, IBookletEntry entry, int page, boolean resetTextField){ - if(booklet.currentEntrySet.getCurrentPage() != null){ - booklet.currentEntrySet.getCurrentPage().onClosed(booklet); - } - booklet.currentEntrySet.setPage(null); - booklet.currentEntrySet.setChapter(null); - - booklet.currentEntrySet.setEntry(entry); - booklet.indexPageAmount = entry == null ? 1 : entry.getChapters().size()/booklet.chapterButtons.length+1; - booklet.currentEntrySet.setPageInIndex(entry == null ? 1 : (booklet.indexPageAmount <= page || page <= 0 ? booklet.indexPageAmount : page)); - - booklet.buttonPreviousScreen.visible = entry != null; - booklet.buttonForward.visible = booklet.currentEntrySet.getPageInIndex() < booklet.indexPageAmount; - booklet.buttonBackward.visible = booklet.currentEntrySet.getPageInIndex() > 1; - - booklet.buttonViewOnline.visible = false; - - for(int i = 0; i < booklet.chapterButtons.length; i++){ - IndexButton button = (IndexButton)booklet.chapterButtons[i]; - if(entry == null){ - if(i >= GuiBooklet.INDEX_BUTTONS_OFFSET){ - boolean entryExists = ActuallyAdditionsAPI.BOOKLET_ENTRIES.size() > i-GuiBooklet.INDEX_BUTTONS_OFFSET; - button.visible = entryExists; - if(entryExists){ - button.displayString = "- "+ActuallyAdditionsAPI.BOOKLET_ENTRIES.get(i-GuiBooklet.INDEX_BUTTONS_OFFSET).getLocalizedNameWithFormatting(); - button.chap = null; - } - } - else{ - button.visible = false; - } - } - else{ - boolean entryExists = entry.getChapters().size() > i+(booklet.chapterButtons.length*booklet.currentEntrySet.getPageInIndex()-booklet.chapterButtons.length); - button.visible = entryExists; - if(entryExists){ - IBookletChapter chap = entry.getChapters().get(i+(booklet.chapterButtons.length*booklet.currentEntrySet.getPageInIndex()-booklet.chapterButtons.length)); - button.displayString = chap.getLocalizedNameWithFormatting(); - button.chap = chap; - } - } - } - - if(resetTextField){ - booklet.searchField.setText(""); - updateSearchBar(booklet); - } - - booklet.shouldSaveDataNextClose = true; - } - - /** - * Called when one of the buttons to open an index or a chapter is pressed - */ - @SideOnly(Side.CLIENT) - public static void handleChapterButtonClick(GuiBooklet booklet, GuiButton button){ - int place = ArrayUtils.indexOf(booklet.chapterButtons, button); - if(place >= 0){ - if(booklet.currentEntrySet.getCurrentEntry() != null){ - if(booklet.currentEntrySet.getCurrentChapter() == null){ - if(place < booklet.currentEntrySet.getCurrentEntry().getChapters().size()){ - //Clear the search bar when entering a chapter - booklet.searchField.setText(""); - updateSearchBar(booklet); - - IBookletChapter chap = booklet.currentEntrySet.getCurrentEntry().getChapters().get(place+(booklet.chapterButtons.length*booklet.currentEntrySet.getPageInIndex()-booklet.chapterButtons.length)); - openChapter(booklet, chap, chap.getPages()[0]); - } - } - } - else{ - if(place-GuiBooklet.INDEX_BUTTONS_OFFSET < ActuallyAdditionsAPI.BOOKLET_ENTRIES.size()){ - openIndexEntry(booklet, ActuallyAdditionsAPI.BOOKLET_ENTRIES.get(place-GuiBooklet.INDEX_BUTTONS_OFFSET), 1, true); - } - } - } - } - - /** - * Opens a chapter in the booklet. - * Can only be done when the chapter is not null and an index entry is opened in the booklet - */ - @SideOnly(Side.CLIENT) - public static void openChapter(GuiBooklet booklet, IBookletChapter chapter, BookletPage page){ - if(chapter == null || booklet.currentEntrySet.getCurrentEntry() == null){ - return; - } - - booklet.currentEntrySet.setChapter(chapter); - - if(booklet.currentEntrySet.getCurrentPage() != null){ - booklet.currentEntrySet.getCurrentPage().onClosed(booklet); - } - BookletPage pageToSet = page != null && doesChapterHavePage(chapter, page) ? page : chapter.getPages()[0]; - booklet.currentEntrySet.setPage(pageToSet); - pageToSet.onOpened(booklet); - - booklet.buttonForward.visible = getNextPage(chapter, booklet.currentEntrySet.getCurrentPage()) != null; - booklet.buttonBackward.visible = getPrevPage(chapter, booklet.currentEntrySet.getCurrentPage()) != null; - booklet.buttonPreviousScreen.visible = true; - - booklet.buttonViewOnline.visible = true; - - for(GuiButton chapterButton : booklet.chapterButtons){ - chapterButton.visible = false; - } - - booklet.shouldSaveDataNextClose = true; - } - - /** - * Checks if a chapter has a certain page - */ - @SideOnly(Side.CLIENT) - private static boolean doesChapterHavePage(IBookletChapter chapter, BookletPage page){ - for(BookletPage aPage : chapter.getPages()){ - if(aPage == page){ - return true; - } - } - return false; - } - - /** - * Gets the next available page in the booklet (or null if there is none) - */ - @SideOnly(Side.CLIENT) - private static BookletPage getNextPage(IBookletChapter chapter, BookletPage page){ - for(int i = 0; i < chapter.getPages().length; i++){ - if(chapter.getPages()[i] == page){ - if(i+1 < chapter.getPages().length){ - return chapter.getPages()[i+1]; - } - } - } - return null; - } - - /** - * Gets the previous available page in the booklet (or null if there is none) - */ - @SideOnly(Side.CLIENT) - private static BookletPage getPrevPage(IBookletChapter chapter, BookletPage page){ - for(int i = 0; i < chapter.getPages().length; i++){ - if(chapter.getPages()[i] == page){ - if(i-1 >= 0){ - return chapter.getPages()[i-1]; - } - } - } - return null; - } - - /** - * Called when the "next page"-button is pressed - */ - @SideOnly(Side.CLIENT) - public static void handleNextPage(GuiBooklet booklet){ - if(booklet.currentEntrySet.getCurrentEntry() != null){ - if(booklet.currentEntrySet.getCurrentPage() != null){ - BookletPage page = getNextPage(booklet.currentEntrySet.getCurrentChapter(), booklet.currentEntrySet.getCurrentPage()); - if(page != null){ - booklet.currentEntrySet.getCurrentPage().onClosed(booklet); - booklet.currentEntrySet.setPage(page); - page.onOpened(booklet); - } - - booklet.buttonForward.visible = getNextPage(booklet.currentEntrySet.getCurrentChapter(), booklet.currentEntrySet.getCurrentPage()) != null; - booklet.buttonBackward.visible = getPrevPage(booklet.currentEntrySet.getCurrentChapter(), booklet.currentEntrySet.getCurrentPage()) != null; - } - else{ - if(booklet.currentEntrySet.getPageInIndex()+1 <= booklet.indexPageAmount){ - openIndexEntry(booklet, booklet.currentEntrySet.getCurrentEntry(), booklet.currentEntrySet.getPageInIndex()+1, !(booklet.currentEntrySet.getCurrentEntry() instanceof BookletEntryAllSearch)); - } - } - } - - booklet.shouldSaveDataNextClose = true; - } - - /** - * Called when the "previous page"-button is pressed - */ - @SideOnly(Side.CLIENT) - public static void handlePreviousPage(GuiBooklet booklet){ - if(booklet.currentEntrySet.getCurrentEntry() != null){ - if(booklet.currentEntrySet.getCurrentPage() != null){ - BookletPage page = getPrevPage(booklet.currentEntrySet.getCurrentChapter(), booklet.currentEntrySet.getCurrentPage()); - if(page != null){ - booklet.currentEntrySet.getCurrentPage().onClosed(booklet); - booklet.currentEntrySet.setPage(page); - page.onOpened(booklet); - } - - booklet.buttonForward.visible = getNextPage(booklet.currentEntrySet.getCurrentChapter(), booklet.currentEntrySet.getCurrentPage()) != null; - booklet.buttonBackward.visible = getPrevPage(booklet.currentEntrySet.getCurrentChapter(), booklet.currentEntrySet.getCurrentPage()) != null; - } - else{ - if(booklet.currentEntrySet.getPageInIndex()-1 > 0){ - openIndexEntry(booklet, booklet.currentEntrySet.getCurrentEntry(), booklet.currentEntrySet.getPageInIndex()-1, !(booklet.currentEntrySet.getCurrentEntry() instanceof BookletEntryAllSearch)); - } - } - } - - booklet.shouldSaveDataNextClose = true; - } - - public static BookletPage getFirstPageForStack(ItemStack stack){ - ArrayList pages = getPagesForStack(stack); - return pages.isEmpty() ? null : pages.get(0); - } - - public static BookletPage getFirstPageForStack(FluidStack stack){ - ArrayList pages = getPagesForStack(stack); - return pages.isEmpty() ? null : pages.get(0); - } - - public static ArrayList getPagesForStack(ItemStack stack){ - ArrayList possiblePages = new ArrayList(); - for(BookletPage page : ActuallyAdditionsAPI.BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA){ - if(ItemUtil.contains(page.getItemStacksForPage(), stack, page.arePageStacksWildcard)){ - possiblePages.add(page); - } - } - return possiblePages; - } - - public static ArrayList getPagesForStack(FluidStack stack){ - ArrayList possiblePages = new ArrayList(); - for(BookletPage page : ActuallyAdditionsAPI.BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA){ - for(FluidStack pageStack : page.getFluidStacksForPage()){ - if(pageStack != null && pageStack.isFluidEqual(stack)){ - possiblePages.add(page); - break; - } - } - } - return possiblePages; - } - - @SideOnly(Side.CLIENT) - public static void saveBookPage(GuiBooklet gui, NBTTagCompound compound){ - //Save Entry etc. - NBTTagCompound tag = new NBTTagCompound(); - gui.currentEntrySet.writeToNBT(tag); - compound.setTag("SavedEntry", tag); - compound.setString("SearchWord", gui.searchField.getText()); - - //Save Bookmarks - NBTTagList list = new NBTTagList(); - for(int i = 0; i < gui.bookmarkButtons.length; i++){ - BookmarkButton button = gui.bookmarkButtons[i]; - - NBTTagCompound buttonTag = new NBTTagCompound(); - button.assignedEntry.writeToNBT(buttonTag); - list.appendTag(buttonTag); - } - compound.setTag("Bookmarks", list); - } - - @SideOnly(Side.CLIENT) - public static void openLastBookPage(GuiBooklet gui, NBTTagCompound compound){ - //Open Entry etc. - EntrySet set = new EntrySet(null); - set.readFromNBT(compound.getCompoundTag("SavedEntry")); - if(set != null){ - - BookletUtils.openIndexEntry(gui, set.getCurrentEntry(), set.getPageInIndex(), true); - if(set.getCurrentChapter() != null){ - BookletUtils.openChapter(gui, set.getCurrentChapter(), set.getCurrentPage()); - } - - String searchText = compound.getString("SearchWord"); - if(!searchText.isEmpty()){ - gui.searchField.setText(searchText); - BookletUtils.updateSearchBar(gui); - } - } - else{ - //If everything fails, initialize the front page - BookletUtils.openIndexEntry(gui, null, 1, true); - } - - //Load Bookmarks - NBTTagList list = compound.getTagList("Bookmarks", 10); - if(list != null){ - for(int i = 0; i < list.tagCount(); i++){ - BookmarkButton button = gui.bookmarkButtons[i]; - button.assignedEntry.readFromNBT(list.getCompoundTagAt(i)); - } - } - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBooklet.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBooklet.java deleted file mode 100644 index 4ed2dd648..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBooklet.java +++ /dev/null @@ -1,559 +0,0 @@ -/* - * This file ("GuiBooklet.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet; - -import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.api.internal.IEntrySet; -import de.ellpeck.actuallyadditions.mod.booklet.button.BookmarkButton; -import de.ellpeck.actuallyadditions.mod.booklet.button.IndexButton; -import de.ellpeck.actuallyadditions.mod.booklet.button.TexturedButton; -import de.ellpeck.actuallyadditions.mod.booklet.chapter.BookletChapter; -import de.ellpeck.actuallyadditions.mod.booklet.entry.EntrySet; -import de.ellpeck.actuallyadditions.mod.config.GuiConfiguration; -import de.ellpeck.actuallyadditions.mod.data.PlayerData; -import de.ellpeck.actuallyadditions.mod.items.ItemBooklet; -import de.ellpeck.actuallyadditions.mod.misc.SoundHandler; -import de.ellpeck.actuallyadditions.mod.network.PacketHandlerHelper; -import de.ellpeck.actuallyadditions.mod.update.UpdateChecker; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.client.audio.PositionedSoundRecord; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.GuiTextField; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.init.SoundEvents; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SideOnly(Side.CLIENT) -public class GuiBooklet extends GuiScreen implements IBookletGui{ - - public static final ResourceLocation RES_LOC = AssetUtil.getBookletGuiLocation("guiBooklet"); - public static final ResourceLocation RES_LOC_ADDON = AssetUtil.getBookletGuiLocation("guiBookletAddon"); - - public static final int CHAPTER_BUTTONS_AMOUNT = 13; - public static final int INDEX_BUTTONS_OFFSET = 3; - private static final int[] AND_HIS_NAME_IS = new int[]{Keyboard.KEY_C, Keyboard.KEY_E, Keyboard.KEY_N, Keyboard.KEY_A}; - public final int xSize; - public final int ySize; - public final IEntrySet currentEntrySet = new EntrySet(null); - public final GuiButton[] chapterButtons = new GuiButton[CHAPTER_BUTTONS_AMOUNT]; - public final BookmarkButton[] bookmarkButtons = new BookmarkButton[8]; - public final GuiScreen parentScreen; - private final boolean tryOpenMainPage; - private final boolean saveOnClose; - public int guiLeft; - public int guiTop; - public int indexPageAmount; - public GuiButton buttonForward; - public GuiButton buttonBackward; - public GuiButton buttonPreviousScreen; - public GuiButton buttonUpdate; - public GuiButton buttonTwitter; - public GuiButton buttonForum; - public GuiButton buttonAchievements; - public GuiButton buttonConfig; - public GuiButton buttonWebsite; - public GuiButton buttonPatreon; - public GuiButton buttonViewOnline; - public GuiTextField searchField; - public boolean shouldSaveDataNextClose; - public String bookletName; - public GuiButton buttonIntroduction; - private int ticksElapsed; - private boolean mousePressed; - private int hisNameIsAt; - - public GuiBooklet(GuiScreen parentScreen, boolean tryOpenMainPage, boolean saveOnClose){ - this.xSize = 146; - this.ySize = 180; - this.parentScreen = parentScreen; - this.tryOpenMainPage = tryOpenMainPage; - this.saveOnClose = saveOnClose; - } - - public FontRenderer getFontRenderer(){ - return this.fontRendererObj; - } - - @Override - public List getButtonList(){ - return this.buttonList; - } - - @Override - public void drawScreen(int x, int y, float f){ - //Fixes Unicode flag - boolean unicodeBefore = this.fontRendererObj.getUnicodeFlag(); - this.fontRendererObj.setUnicodeFlag(true); - - //To Player: - // - //FastCraft's a must, definitely - //But the bigger unicode option sucks real - //It screws with my book and makes me feel ill - //So don't fuck with everything unintentionally - // - //(This fixes your fuckery) - GlStateManager.scale(1.0F, 1.0F, 1.0F); - - //Draws the Background - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - this.mc.getTextureManager().bindTexture(RES_LOC); - this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); - - //Draws the search bar - this.drawTexturedModalRect(this.guiLeft+146, this.guiTop+160, 146, 80, 70, 14); - if(!this.searchField.isFocused() && (this.searchField.getText() == null || this.searchField.getText().isEmpty())){ - this.drawString(this.fontRendererObj, TextFormatting.ITALIC+"Click to search...", this.guiLeft+148, this.guiTop+162, 0xFFFFFF); - } - - //Draws Achievement Info - BookletUtils.drawAchievementInfo(this, true, x, y); - - this.fontRendererObj.setUnicodeFlag(false); - //Draws the title - BookletUtils.drawTitle(this); - - if(this.buttonIntroduction.visible){ - StringUtil.drawSplitString(this.fontRendererObj, TextFormatting.GREEN+"Hi! It looks like you're using this manual! Would you like help? "+TextFormatting.RESET+"\nClick the button below to save a couple of "+TextFormatting.GOLD+"useful chapters as bookmarks"+TextFormatting.RESET+" on the bottom of the GUI! \nIf you don't want this, shift-click the button instead.", this.guiLeft+150, this.guiTop+10, 100, 0xFFFFFF, true); - - this.mc.getTextureManager().bindTexture(RES_LOC_ADDON); - this.drawTexturedModalRect(this.guiLeft+240, this.guiTop-10, 226, 0, 30, 55); - this.mc.getTextureManager().bindTexture(RES_LOC); - } - this.fontRendererObj.setUnicodeFlag(true); - - //Pre-Renders the current page's content etc. - BookletUtils.renderPre(this, x, y, this.ticksElapsed, this.mousePressed); - - //Buttons and search field - if(this.currentEntrySet.getCurrentPage() != null){ - this.fontRendererObj.setUnicodeFlag(false); - } - for(GuiButton button : this.buttonList){ - button.drawButton(this.mc, x, y); - } - this.fontRendererObj.setUnicodeFlag(true); - - this.searchField.drawTextBox(); - - //Renders the current page's content - if(this.currentEntrySet.getCurrentEntry() != null && this.currentEntrySet.getCurrentChapter() != null && this.currentEntrySet.getCurrentPage() != null){ - this.currentEntrySet.getCurrentPage().render(this, x, y, this.ticksElapsed, this.mousePressed); - } - - this.fontRendererObj.setUnicodeFlag(false); - //Draws hovering texts for buttons - BookletUtils.doHoverTexts(this, x, y); - BookletUtils.drawAchievementInfo(this, false, x, y); - this.fontRendererObj.setUnicodeFlag(unicodeBefore); - - //Resets mouse - this.mousePressed = false; - } - - @Override - public void keyTyped(char theChar, int key){ - if(!this.searchField.isFocused() && AND_HIS_NAME_IS.length > this.hisNameIsAt && AND_HIS_NAME_IS[this.hisNameIsAt] == key){ - if(this.hisNameIsAt+1 >= AND_HIS_NAME_IS.length){ - Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundHandler.duhDuhDuhDuuuh, 0.5F)); - ModUtil.LOGGER.info("AND HIS NAME IS JOHN CENA DUH DUH DUH DUUUH"); - this.hisNameIsAt = 0; - } - else{ - this.hisNameIsAt++; - } - } - else{ - this.hisNameIsAt = 0; - - if(key == Keyboard.KEY_ESCAPE || (key == this.mc.gameSettings.keyBindInventory.getKeyCode() && !this.searchField.isFocused())){ - if(this.parentScreen != null){ - this.mc.displayGuiScreen(this.parentScreen); - } - else{ - this.mc.displayGuiScreen(null); - this.mc.setIngameFocus(); - } - } - else if(this.searchField.isFocused()){ - this.searchField.textboxKeyTyped(theChar, key); - BookletUtils.updateSearchBar(this); - } - } - - } - - @Override - public void drawHoveringText(List list, int x, int y){ - super.drawHoveringText(list, x, y); - } - - @Override - protected void mouseClicked(int par1, int par2, int par3) throws IOException{ - this.searchField.mouseClicked(par1, par2, par3); - //Left mouse button - if(par3 == 0 && this.currentEntrySet.getCurrentChapter() != null){ - this.mousePressed = true; - } - //Right mouse button - else if(par3 == 1){ - if(this.currentEntrySet.getCurrentChapter() != null){ - BookletUtils.openIndexEntry(this, this.currentEntrySet.getCurrentEntry(), this.currentEntrySet.getPageInIndex(), true); - } - else{ - BookletUtils.openIndexEntry(this, null, 1, true); - } - } - super.mouseClicked(par1, par2, par3); - } - - @Override - public void actionPerformed(GuiButton button){ - if(this.currentEntrySet.getCurrentPage() != null){ - if(this.currentEntrySet.getCurrentPage().onActionPerformed(this, button)){ - return; - } - } - - //Handles introduction - if(button == this.buttonIntroduction){ - this.buttonIntroduction.visible = false; - - if(!isShiftKeyDown()){ - for(int i = 0; i < InitBooklet.chaptersIntroduction.length; i++){ - BookletChapter chap = InitBooklet.chaptersIntroduction[i]; - this.bookmarkButtons[i].assignedEntry.setEntry(chap.getPages()[0], chap, chap.getEntry(), ActuallyAdditionsAPI.BOOKLET_ENTRIES.indexOf(chap.getEntry())/GuiBooklet.CHAPTER_BUTTONS_AMOUNT+1); - } - this.shouldSaveDataNextClose = true; - } - - NBTTagCompound extraData = new NBTTagCompound(); - extraData.setBoolean("IntroductionDone", true); - PacketHandlerHelper.sendChangePlayerDataPacket(extraData); - } - //Handles update - else if(button == this.buttonUpdate){ - if(UpdateChecker.needsUpdateNotify){ - BookletUtils.openBrowser(UpdateChecker.CHANGELOG_LINK, UpdateChecker.DOWNLOAD_LINK); - } - } - //Handles View Online - else if(button == this.buttonViewOnline){ - IBookletChapter chapter = this.currentEntrySet.getCurrentChapter(); - if(chapter != null){ - BookletUtils.openBrowser("http://ellpeck.de/actaddmanual/#"+chapter.getIdentifier()); - } - } - //Handles Website - else if(button == this.buttonWebsite){ - BookletUtils.openBrowser("http://ellpeck.de"); - } - //Handles Patreon - else if(button == this.buttonPatreon){ - BookletUtils.openBrowser("http://www.patreon.com/Ellpeck"); - } - //Handles Twitter - else if(button == this.buttonTwitter){ - BookletUtils.openBrowser("http://twitter.com/ActAddMod"); - } - //Handles forum - else if(button == this.buttonForum){ - BookletUtils.openBrowser("http://ellpeck.de/actadd"); - } - //Handles config - else if(button == this.buttonConfig){ - this.mc.displayGuiScreen(new GuiConfiguration(this)); - } - //Handles achievements - else if(button == this.buttonAchievements){ - this.mc.displayGuiScreen(new GuiAAAchievements(this, this.mc.thePlayer.getStatFileWriter())); - } - else if(button == this.buttonForward){ - BookletUtils.handleNextPage(this); - } - else if(button == this.buttonBackward){ - BookletUtils.handlePreviousPage(this); - } - //Handles gonig from page to chapter or from chapter to index - else if(button == this.buttonPreviousScreen){ - if(this.currentEntrySet.getCurrentChapter() != null){ - BookletUtils.openIndexEntry(this, this.currentEntrySet.getCurrentEntry(), this.currentEntrySet.getPageInIndex(), true); - } - else{ - BookletUtils.openIndexEntry(this, null, 1, true); - } - } - //Handles Bookmark button - else if(button instanceof BookmarkButton){ - ((BookmarkButton)button).onPressed(); - } - else{ - BookletUtils.handleChapterButtonClick(this, button); - } - } - - @Override - public void initGui(){ - int flavor = 1; - if(this.mc.theWorld.rand.nextFloat() <= 0.1){ - flavor = MathHelper.getRandomIntegerInRange(this.mc.theWorld.rand, 2, 7); - } - this.bookletName = "info."+ModUtil.MOD_ID+".booklet.manualName.1."+flavor; - - this.guiLeft = (this.width-this.xSize)/2; - this.guiTop = (this.height-this.ySize)/2-10; - - this.buttonForward = new TexturedButton(0, this.guiLeft+this.xSize-26, this.guiTop+this.ySize+1, 164, 0, 18, 10, Collections.singletonList(TextFormatting.GOLD+"Next Page")); - this.buttonList.add(this.buttonForward); - - this.buttonBackward = new TexturedButton(1, this.guiLeft+8, this.guiTop+this.ySize+1, 146, 0, 18, 10, Collections.singletonList(TextFormatting.GOLD+"Previous Page")); - this.buttonList.add(this.buttonBackward); - - this.buttonPreviousScreen = new TexturedButton(2, this.guiLeft+this.xSize/2-7, this.guiTop+this.ySize+1, 182, 0, 15, 10, Collections.singletonList(TextFormatting.GOLD+"Back")); - this.buttonList.add(this.buttonPreviousScreen); - - ArrayList updateHover = new ArrayList(); - if(UpdateChecker.checkFailed){ - updateHover.add(ITextComponent.Serializer.jsonToComponent(StringUtil.localize("info."+ModUtil.MOD_ID+".update.failed")).getFormattedText()); - } - else if(UpdateChecker.needsUpdateNotify){ - updateHover.add(ITextComponent.Serializer.jsonToComponent(StringUtil.localize("info."+ModUtil.MOD_ID+".update.generic")).getFormattedText()); - updateHover.add(ITextComponent.Serializer.jsonToComponent(StringUtil.localizeFormatted("info."+ModUtil.MOD_ID+".update.versionCompare", ModUtil.VERSION, UpdateChecker.updateVersionString)).getFormattedText()); - updateHover.add(StringUtil.localize("info."+ModUtil.MOD_ID+".update.buttonOptions")); - } - this.buttonUpdate = new TexturedButton(4, this.guiLeft-11, this.guiTop-11, 245, 0, 11, 11, updateHover); - this.buttonUpdate.visible = UpdateChecker.needsUpdateNotify || UpdateChecker.checkFailed; - this.buttonList.add(this.buttonUpdate); - - this.buttonTwitter = new TexturedButton(5, this.guiLeft, this.guiTop+10, 213, 0, 8, 8, Collections.singletonList(TextFormatting.GOLD+"Open @ActAddMod on Twitter in Browser")); - this.buttonList.add(this.buttonTwitter); - - this.buttonForum = new TexturedButton(6, this.guiLeft, this.guiTop+20, 221, 0, 8, 8, Collections.singletonList(TextFormatting.GOLD+"Open CurseForge Page in Browser")); - this.buttonList.add(this.buttonForum); - - this.buttonAchievements = new TexturedButton(7, this.guiLeft+138, this.guiTop, 205, 0, 8, 8, Collections.singletonList(TextFormatting.GOLD+"Show Achievements")); - this.buttonList.add(this.buttonAchievements); - - ArrayList websiteHover = new ArrayList(); - websiteHover.add(TextFormatting.GOLD+"Open Author's Website"); - websiteHover.add("(There's some cool stuff there!)"); - websiteHover.add(TextFormatting.GRAY+""+TextFormatting.ITALIC+"Would you call this Product Placement?"); - this.buttonWebsite = new TexturedButton(-99, this.guiLeft, this.guiTop+30, 229, 0, 8, 8, websiteHover); - this.buttonList.add(this.buttonWebsite); - - List patreonHover = new ArrayList(); - patreonHover.add("Like the mod?"); - patreonHover.add("Why don't support me on "+TextFormatting.GOLD+"Patreon"+TextFormatting.RESET+"?"); - this.buttonPatreon = new TexturedButton(-100, this.guiLeft, this.guiTop, 237, 0, 8, 8, patreonHover); - this.buttonList.add(this.buttonPatreon); - - this.buttonViewOnline = new TexturedButton(-101, this.guiLeft+146, this.guiTop+180, 245, 44, 11, 11, Collections.singletonList(TextFormatting.GOLD+"View Online")); - this.buttonList.add(this.buttonViewOnline); - - ArrayList configHover = new ArrayList(); - configHover.add(TextFormatting.GOLD+"Show Configuration GUI"); - configHover.addAll(this.fontRendererObj.listFormattedStringToWidth("It is highly recommended that you restart your game after changing anything as that prevents possible bugs occuring!", 200)); - this.buttonConfig = new TexturedButton(8, this.guiLeft+138, this.guiTop+10, 197, 0, 8, 8, configHover); - this.buttonList.add(this.buttonConfig); - - for(int i = 0; i < this.chapterButtons.length; i++){ - this.chapterButtons[i] = new IndexButton(9+i, this.guiLeft+15, this.guiTop+10+(i*12), 115, 10, "", this); - this.buttonList.add(this.chapterButtons[i]); - } - - for(int i = 0; i < this.bookmarkButtons.length; i++){ - int x = this.guiLeft+this.xSize/2-(this.bookmarkButtons.length/2*16)+(i*16); - this.bookmarkButtons[i] = new BookmarkButton(this.chapterButtons[this.chapterButtons.length-1].id+1+i, x, this.guiTop+this.ySize+13, this); - this.buttonList.add(this.bookmarkButtons[i]); - } - - this.searchField = new GuiTextField(4500, this.fontRendererObj, this.guiLeft+148, this.guiTop+162, 70, 10); - this.searchField.setMaxStringLength(30); - this.searchField.setEnableBackgroundDrawing(false); - - this.currentEntrySet.removeEntry(); - - PlayerData.PlayerSave data = PlayerData.getDataFromPlayer(Minecraft.getMinecraft().thePlayer); - - this.buttonIntroduction = new TexturedButton(-3531, this.guiLeft+150, this.guiTop+128, 245, 0, 11, 11); - this.buttonList.add(this.buttonIntroduction); - this.buttonIntroduction.visible = !data.theCompound.getBoolean("IntroductionDone"); - - if(ItemBooklet.forcedEntry == null){ - //Open last entry or introductory entry - if(this.tryOpenMainPage && !data.theCompound.getBoolean("BookAlreadyOpened")){ - BookletUtils.openIndexEntry(this, InitBooklet.chapterIntro.entry, 1, true); - BookletUtils.openChapter(this, InitBooklet.chapterIntro, null); - - NBTTagCompound extraData = new NBTTagCompound(); - extraData.setBoolean("BookAlreadyOpened", true); - PacketHandlerHelper.sendChangePlayerDataPacket(extraData); - } - else{ - BookletUtils.openLastBookPage(this, data.theCompound.getCompoundTag("BookletData")); - } - this.shouldSaveDataNextClose = false; - } - else{ - //Open forced entry - BookletUtils.openIndexEntry(this, ItemBooklet.forcedEntry.getCurrentEntry(), ItemBooklet.forcedEntry.getPageInIndex(), true); - BookletUtils.openChapter(this, ItemBooklet.forcedEntry.getCurrentChapter(), ItemBooklet.forcedEntry.getCurrentPage()); - ItemBooklet.forcedEntry = null; - - this.shouldSaveDataNextClose = true; - } - - } - - @Override - //For scrolling through pages - public void handleMouseInput() throws IOException{ - int wheel = Mouse.getEventDWheel(); - if(wheel != 0){ - if(wheel < 0){ - BookletUtils.handleNextPage(this); - } - else if(wheel > 0){ - BookletUtils.handlePreviousPage(this); - } - } - super.handleMouseInput(); - } - - @Override - public void updateScreen(){ - super.updateScreen(); - this.searchField.updateCursorCounter(); - - if(this.currentEntrySet.getCurrentEntry() != null && this.currentEntrySet.getCurrentChapter() != null && this.currentEntrySet.getCurrentPage() != null){ - this.currentEntrySet.getCurrentPage().updateScreen(this.ticksElapsed); - } - - boolean buttonThere = UpdateChecker.needsUpdateNotify || UpdateChecker.checkFailed; - this.buttonUpdate.visible = buttonThere; - if(buttonThere){ - if(this.ticksElapsed%8 == 0){ - TexturedButton button = (TexturedButton)this.buttonUpdate; - button.setTexturePos(245, button.texturePosY == 0 ? 22 : 0); - } - } - - this.ticksElapsed++; - } - - @Override - public void onGuiClosed(){ - if(this.saveOnClose && this.shouldSaveDataNextClose){ - Minecraft mc = Minecraft.getMinecraft(); - //Happens when you get thrown out with the book open - if(mc.theWorld != null && mc.thePlayer != null){ - NBTTagCompound bookletData = new NBTTagCompound(); - BookletUtils.saveBookPage(this, bookletData); - - NBTTagCompound extraData = new NBTTagCompound(); - extraData.setTag("BookletData", bookletData); - - PacketHandlerHelper.sendChangePlayerDataPacket(extraData); - } - } - } - - @Override - public boolean doesGuiPauseGame(){ - return false; - } - - @Override - public void renderTooltipAndTransferButton(BookletPage from, ItemStack stack, int x, int y, boolean renderTransferButton, boolean mousePressed){ - boolean flagBefore = this.mc.fontRendererObj.getUnicodeFlag(); - this.mc.fontRendererObj.setUnicodeFlag(false); - - List list = stack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips); - - for(int k = 0; k < list.size(); ++k){ - if(k == 0){ - list.set(k, stack.getRarity().rarityColor+(String)list.get(k)); - } - else{ - list.set(k, TextFormatting.GRAY+(String)list.get(k)); - } - } - - if(renderTransferButton){ - BookletPage page = BookletUtils.getFirstPageForStack(stack); - if(page != null && page != from){ - list.add(from.getClickToSeeRecipeString()); - - if(mousePressed){ - BookletUtils.openIndexEntry(this, page.getChapter().getEntry(), ActuallyAdditionsAPI.BOOKLET_ENTRIES.indexOf(page.getChapter().getEntry())/GuiBooklet.CHAPTER_BUTTONS_AMOUNT+1, true); - BookletUtils.openChapter(this, page.getChapter(), page); - Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.UI_BUTTON_CLICK, 1.0F)); - } - } - } - - this.drawHoveringText(list, x, y); - - this.mc.fontRendererObj.setUnicodeFlag(flagBefore); - } - - @Override - public int getXSize(){ - return this.xSize; - } - - @Override - public int getYSize(){ - return this.ySize; - } - - @Override - public int getGuiLeft(){ - return this.guiLeft; - } - - @Override - public int getGuiTop(){ - return this.guiTop; - } - - @Override - public void drawRect(int startX, int startY, int u, int v, int xSize, int ySize){ - this.drawTexturedModalRect(startX, startY, u, v, xSize, ySize); - } - - @Override - public IEntrySet getCurrentEntrySet(){ - return this.currentEntrySet; - } -} \ No newline at end of file diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBookletStand.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBookletStand.java deleted file mode 100644 index 1bf5858fe..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiBookletStand.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file ("GuiBookletStand.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet; - -import de.ellpeck.actuallyadditions.mod.network.PacketClientToServer; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; -import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase; -import de.ellpeck.actuallyadditions.mod.tile.TileEntityBookletStand; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class GuiBookletStand extends GuiBooklet{ - - private final TileEntityBookletStand theStand; - private GuiButton buttonSetPage; - - public GuiBookletStand(TileEntityBase theStand){ - super(null, false, false); - this.theStand = (TileEntityBookletStand)theStand; - } - - @Override - public void actionPerformed(GuiButton button){ - if(button == this.buttonSetPage){ - NBTTagCompound compound = new NBTTagCompound(); - compound.setInteger("X", this.theStand.getPos().getX()); - compound.setInteger("Y", this.theStand.getPos().getY()); - compound.setInteger("Z", this.theStand.getPos().getZ()); - compound.setInteger("PlayerID", Minecraft.getMinecraft().thePlayer.getEntityId()); - compound.setInteger("WorldID", this.theStand.getWorld().provider.getDimension()); - NBTTagCompound tag = new NBTTagCompound(); - this.currentEntrySet.writeToNBT(tag); - compound.setTag("EntrySet", tag); - PacketHandler.theNetwork.sendToServer(new PacketClientToServer(compound, PacketHandler.BOOKLET_STAND_BUTTON_HANDLER)); - } - super.actionPerformed(button); - } - - @Override - public void initGui(){ - super.initGui(); - - //Remove Bookmark Buttons - this.buttonIntroduction.visible = false; - for(GuiButton bookmarkButton : this.bookmarkButtons){ - bookmarkButton.visible = false; - } - - this.buttonSetPage = new GuiButton(-100, this.guiLeft+this.xSize+10, this.guiTop+10, 100, 20, "Set Page"){ - @Override - public void drawButton(Minecraft mc, int x, int y){ - boolean unicodeBefore = mc.fontRendererObj.getUnicodeFlag(); - mc.fontRendererObj.setUnicodeFlag(false); - super.drawButton(mc, x, y); - mc.fontRendererObj.setUnicodeFlag(unicodeBefore); - } - }; - this.buttonList.add(this.buttonSetPage); - - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - if(player != null && player.getName() != null){ - this.buttonSetPage.visible = player.getName().equalsIgnoreCase(this.theStand.assignedPlayer); - } - - //Open the pages the book was assigned - BookletUtils.openIndexEntry(this, this.theStand.assignedEntry.getCurrentEntry(), this.theStand.assignedEntry.getPageInIndex(), true); - BookletUtils.openChapter(this, this.theStand.assignedEntry.getCurrentChapter(), this.theStand.assignedEntry.getCurrentPage()); - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/InitBooklet.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/InitBooklet.java index 064225d50..5d93b3784 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/InitBooklet.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/InitBooklet.java @@ -11,17 +11,15 @@ package de.ellpeck.actuallyadditions.mod.booklet; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.mod.blocks.InitBlocks; import de.ellpeck.actuallyadditions.mod.blocks.metalists.TheColoredLampColors; import de.ellpeck.actuallyadditions.mod.blocks.metalists.TheMiscBlocks; import de.ellpeck.actuallyadditions.mod.booklet.chapter.BookletChapter; -import de.ellpeck.actuallyadditions.mod.booklet.chapter.BookletChapterCoffee; -import de.ellpeck.actuallyadditions.mod.booklet.chapter.BookletChapterCrusher; import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntry; -import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntryAllSearch; +import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntryAllItems; import de.ellpeck.actuallyadditions.mod.booklet.page.*; import de.ellpeck.actuallyadditions.mod.crafting.*; import de.ellpeck.actuallyadditions.mod.fluids.InitFluids; @@ -60,40 +58,43 @@ public final class InitBooklet{ ActuallyAdditionsAPI.entryItemsNonRF = new BookletEntry("itemsNoRF"); ActuallyAdditionsAPI.entryItemsRF = new BookletEntry("itemsRF"); ActuallyAdditionsAPI.entryMisc = new BookletEntry("misc").setSpecial(); - ActuallyAdditionsAPI.allAndSearch = new BookletEntryAllSearch("allAndSearch").setImportant(); + ActuallyAdditionsAPI.allAndSearch = new BookletEntryAllItems("allAndSearch").setImportant(); } public static void postInit(){ initChapters(); - int totalCount = 0; - int count = 0; + int chapCount = 0; + int pageCount = 0; + int infoCount = 0; for(IBookletEntry entry : ActuallyAdditionsAPI.BOOKLET_ENTRIES){ - for(IBookletChapter chapter : entry.getChapters()){ + for(IBookletChapter chapter : entry.getAllChapters()){ if(!ActuallyAdditionsAPI.ALL_CHAPTERS.contains(chapter)){ ActuallyAdditionsAPI.ALL_CHAPTERS.add(chapter); + chapCount++; } - for(BookletPage page : chapter.getPages()){ + for(IBookletPage page : chapter.getAllPages()){ ItemStack[] items = page.getItemStacksForPage(); FluidStack[] fluids = page.getFluidStacksForPage(); if((items != null && items.length > 0) || (fluids != null && fluids.length > 0)){ if(!ActuallyAdditionsAPI.BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA.contains(page)){ ActuallyAdditionsAPI.BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA.add(page); - count++; + infoCount++; } } - totalCount++; + pageCount++; } } } - ModUtil.LOGGER.info("Registered "+count+" out of "+totalCount+" booklet pages as containing information about items or fluids!"); + ModUtil.LOGGER.info("Registered a total of "+chapCount+" booklet chapters, where "+infoCount+" out of "+pageCount+" booklet pages contain information about items or fluids!"); } private static void initChapters(){ + /* TODO Reenable this //Getting Started chapterIntro = new BookletChapter("intro", ActuallyAdditionsAPI.entryGettingStarted, new ItemStack(InitItems.itemBooklet), new PageTextOnly(1), new PageTextOnly(2), new PageTextOnly(3)); new BookletChapter("reviews", ActuallyAdditionsAPI.entryGettingStarted, new ItemStack(Items.BOOK), new PageTextOnly(1)); @@ -230,5 +231,5 @@ public final class InitBooklet{ new BookletChapter("growthRing", ActuallyAdditionsAPI.entryItemsRF, new ItemStack(InitItems.itemGrowthRing), new PageCrafting(1, ItemCrafting.recipeGrowthRing)); new BookletChapter("waterRemovalRing", ActuallyAdditionsAPI.entryItemsRF, new ItemStack(InitItems.itemWaterRemovalRing), new PageCrafting(1, ItemCrafting.recipeWaterRing)); new BookletChapter("batteries", ActuallyAdditionsAPI.entryItemsRF, new ItemStack(InitItems.itemBatteryTriple), new PageTextOnly(1), new PageCrafting(2, ItemCrafting.recipeBattery).setNoText(), new PageCrafting(3, ItemCrafting.recipeBatteryDouble).setNoText(), new PageCrafting(4, ItemCrafting.recipeBatteryTriple).setNoText(), new PageCrafting(5, ItemCrafting.recipeBatteryQuadruple).setNoText(), new PageCrafting(6, ItemCrafting.recipeBatteryQuintuple).setNoText()); - } + */} } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/BookmarkButton.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/BookmarkButton.java deleted file mode 100644 index 4d7bf7aef..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/BookmarkButton.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file ("BookmarkButton.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.button; - -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.booklet.entry.EntrySet; -import de.ellpeck.actuallyadditions.mod.items.InitItems; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.item.ItemStack; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.ArrayList; - -@SideOnly(Side.CLIENT) -public class BookmarkButton extends GuiButton{ - - private final GuiBooklet booklet; - public EntrySet assignedEntry = new EntrySet(null); - - public BookmarkButton(int id, int x, int y, GuiBooklet booklet){ - super(id, x, y, 16, 16, ""); - this.booklet = booklet; - } - - public void onPressed(){ - if(this.assignedEntry.getCurrentEntry() != null){ - if(GuiScreen.isShiftKeyDown()){ - this.assignedEntry.removeEntry(); - this.booklet.shouldSaveDataNextClose = true; - } - else{ - BookletUtils.openIndexEntry(this.booklet, this.assignedEntry.getCurrentEntry(), this.assignedEntry.getPageInIndex(), true); - BookletUtils.openChapter(this.booklet, this.assignedEntry.getCurrentChapter(), this.assignedEntry.getCurrentPage()); - } - } - else{ - if(this.booklet.currentEntrySet.getCurrentEntry() != null){ - this.assignedEntry.setEntry(this.booklet.currentEntrySet.getCurrentPage(), this.booklet.currentEntrySet.getCurrentChapter(), this.booklet.currentEntrySet.getCurrentEntry(), this.booklet.currentEntrySet.getPageInIndex()); - this.booklet.shouldSaveDataNextClose = true; - } - } - } - - @Override - public void drawButton(Minecraft minecraft, int x, int y){ - if(this.visible){ - minecraft.getTextureManager().bindTexture(GuiBooklet.RES_LOC); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - this.hovered = x >= this.xPosition && y >= this.yPosition && x < this.xPosition+this.width && y < this.yPosition+this.height; - int k = this.getHoverState(this.hovered); - if(k == 0){ - k = 1; - } - - GlStateManager.enableBlend(); - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); - GlStateManager.blendFunc(770, 771); - int renderHeight = 25; - this.drawTexturedModalRect(this.xPosition, this.yPosition, 146+(this.assignedEntry.getCurrentEntry() == null ? 0 : 16), 194-renderHeight+k*renderHeight, this.width, renderHeight); - this.mouseDragged(minecraft, x, y); - - if(this.assignedEntry.getCurrentEntry() != null){ - GlStateManager.pushMatrix(); - AssetUtil.renderStackToGui(this.assignedEntry.getCurrentChapter() != null && this.assignedEntry.getCurrentChapter().getDisplayItemStack() != null ? this.assignedEntry.getCurrentChapter().getDisplayItemStack() : new ItemStack(InitItems.itemBooklet), this.xPosition+2, this.yPosition+1, 0.725F); - GlStateManager.popMatrix(); - } - } - } - - public void drawHover(int mouseX, int mouseY){ - ArrayList list = new ArrayList(); - if(this.assignedEntry.getCurrentEntry() != null){ - if(this.assignedEntry.getCurrentChapter() != null){ - list.add(TextFormatting.GOLD+this.assignedEntry.getCurrentChapter().getLocalizedName()+", Page "+this.assignedEntry.getCurrentPage().getID()); - } - else{ - list.add(TextFormatting.GOLD+this.assignedEntry.getCurrentEntry().getLocalizedName()+", Page "+this.assignedEntry.getPageInIndex()); - } - list.add("Click to open"); - list.add(TextFormatting.ITALIC+"Shift-Click to remove"); - } - else{ - list.add(TextFormatting.GOLD+"None"); - list.add("Click to save current page"); - } - this.booklet.drawHoveringText(list, mouseX, mouseY); - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/IndexButton.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/EntryButton.java similarity index 56% rename from src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/IndexButton.java rename to src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/EntryButton.java index 17776e210..a6ccf9cba 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/IndexButton.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/EntryButton.java @@ -1,5 +1,5 @@ /* - * This file ("IndexButton.java") is part of the Actually Additions mod for Minecraft. + * This file ("EntryButton.java") is part of the Actually Additions mod for Minecraft. * It is created and owned by Ellpeck and distributed * under the Actually Additions License to be found at * http://ellpeck.de/actaddlicense @@ -10,24 +10,23 @@ package de.ellpeck.actuallyadditions.mod.booklet.button; -import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; import de.ellpeck.actuallyadditions.mod.util.AssetUtil; +import de.ellpeck.actuallyadditions.mod.util.StringUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) -public class IndexButton extends GuiButton{ +public class EntryButton extends GuiButton{ - private final GuiBooklet gui; - public IBookletChapter chap; + public ItemStack stackToRender; - public IndexButton(int id, int x, int y, int width, int height, String text, GuiBooklet gui){ + public EntryButton(int id, int x, int y, int width, int height, String text, ItemStack stackToRender){ super(id, x, y, width, height, text); - this.gui = gui; + this.stackToRender = stackToRender; } @Override @@ -41,22 +40,22 @@ public class IndexButton extends GuiButton{ this.mouseDragged(minecraft, mouseX, mouseY); int textOffsetX = 0; - if(this.chap != null){ - if(this.chap.getDisplayItemStack() != null){ - GlStateManager.pushMatrix(); - AssetUtil.renderStackToGui(this.chap.getDisplayItemStack(), this.xPosition-4, this.yPosition, 0.725F); - GlStateManager.popMatrix(); - textOffsetX = 10; - } + if(this.stackToRender != null){ + GlStateManager.pushMatrix(); + AssetUtil.renderStackToGui(this.stackToRender, this.xPosition-4, this.yPosition, 0.725F); + GlStateManager.popMatrix(); + textOffsetX = 10; } + float scale = 0.8F; + if(this.hovered){ GlStateManager.pushMatrix(); - AssetUtil.drawHorizontalGradientRect(this.xPosition+textOffsetX-1, this.yPosition+this.height-1, this.xPosition+this.gui.getFontRenderer().getStringWidth(this.displayString)+textOffsetX+1, this.yPosition+this.height, 0x80 << 24 | 22271, 22271, this.zLevel); + AssetUtil.drawHorizontalGradientRect(this.xPosition+textOffsetX-1, this.yPosition+this.height-2, this.xPosition+(int)(minecraft.fontRendererObj.getStringWidth(this.displayString)*scale)+textOffsetX+1, this.yPosition+this.height-1, 0x80 << 24 | 22271, 22271, this.zLevel); GlStateManager.popMatrix(); } - this.gui.getFontRenderer().drawString(this.displayString, this.xPosition+textOffsetX, this.yPosition+(this.height-8)/2, 0); + StringUtil.renderScaledAsciiString(minecraft.fontRendererObj, this.displayString, this.xPosition+textOffsetX, this.yPosition+(this.height-8)/2, 0, false, scale); } } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapter.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapter.java index 21fb92813..36b3b2e8a 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapter.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapter.java @@ -11,54 +11,42 @@ package de.ellpeck.actuallyadditions.mod.booklet.chapter; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; import net.minecraft.item.ItemStack; import net.minecraft.util.text.TextFormatting; -import org.apache.commons.lang3.ArrayUtils; public class BookletChapter implements IBookletChapter{ - public final BookletPage[] pages; + public final IBookletPage[] pages; public final IBookletEntry entry; public final ItemStack displayStack; private final String identifier; public TextFormatting color; - public BookletChapter(String identifier, IBookletEntry entry, ItemStack displayStack, BookletPage... pages){ - this.pages = pages.clone(); - + public BookletChapter(String identifier, IBookletEntry entry, ItemStack displayStack, IBookletPage... pages){ + this.pages = pages; this.identifier = identifier; - entry.addChapter(this); - ActuallyAdditionsAPI.allAndSearch.addChapter(this); this.entry = entry; this.displayStack = displayStack; + this.color = TextFormatting.RESET; - for(BookletPage page : this.pages){ + this.entry.addChapter(this); + ActuallyAdditionsAPI.allAndSearch.addChapter(this); + + for(IBookletPage page : this.pages){ page.setChapter(this); } - - this.color = TextFormatting.RESET; } @Override - public BookletPage[] getPages(){ + public IBookletPage[] getAllPages(){ return this.pages; } - @Override - public BookletPage getPageById(int id){ - return this.getPages()[id-1]; - } - - @Override - public int getPageId(BookletPage page){ - return ArrayUtils.indexOf(this.getPages(), page)+1; - } - @Override public String getLocalizedName(){ return StringUtil.localize("booklet."+ModUtil.MOD_ID+".chapter."+this.getIdentifier()+".name"); @@ -84,6 +72,16 @@ public class BookletChapter implements IBookletChapter{ return this.identifier; } + @Override + public int getPageNum(IBookletPage page){ + for(int i = 0; i < this.pages.length; i++){ + if(this.pages[i] == page){ + return i+1; + } + } + return -1; + } + public BookletChapter setImportant(){ this.color = TextFormatting.DARK_GREEN; return this; diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCoffee.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCoffee.java deleted file mode 100644 index a48b5464e..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCoffee.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file ("BookletChapterCoffee.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.chapter; - -import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; -import de.ellpeck.actuallyadditions.api.recipe.CoffeeIngredient; -import de.ellpeck.actuallyadditions.mod.booklet.page.BookletPageAA; -import de.ellpeck.actuallyadditions.mod.booklet.page.PageCoffeeRecipe; -import de.ellpeck.actuallyadditions.mod.items.ItemCoffee; -import net.minecraft.item.ItemStack; - -import java.util.ArrayList; -import java.util.Arrays; - -public class BookletChapterCoffee extends BookletChapter{ - - public BookletChapterCoffee(String unlocalizedName, IBookletEntry entry, ItemStack displayStack, BookletPage... pages){ - super(unlocalizedName, entry, displayStack, getPages(pages)); - } - - private static BookletPage[] getPages(BookletPage... pages){ - ArrayList allPages = new ArrayList(); - allPages.addAll(Arrays.asList(pages)); - - for(CoffeeIngredient ingredient : ActuallyAdditionsAPI.COFFEE_MACHINE_INGREDIENTS){ - BookletPageAA page = new PageCoffeeRecipe(allPages.size()+1, ingredient); - if(!(ingredient instanceof ItemCoffee.MilkIngredient)){ - page.setNoText(); - } - allPages.add(page); - } - - return allPages.toArray(new BookletPage[allPages.size()]); - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCrusher.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCrusher.java deleted file mode 100644 index 8307d6262..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterCrusher.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file ("BookletChapterCrusher.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.chapter; - -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; -import de.ellpeck.actuallyadditions.api.recipe.CrusherRecipe; -import de.ellpeck.actuallyadditions.mod.booklet.page.PageCrusherRecipe; -import de.ellpeck.actuallyadditions.mod.crafting.CrusherCrafting; -import net.minecraft.item.ItemStack; - -import java.util.ArrayList; -import java.util.Arrays; - -public class BookletChapterCrusher extends BookletChapter{ - - public BookletChapterCrusher(String unlocalizedName, IBookletEntry entry, ItemStack displayStack, BookletPage... pages){ - super(unlocalizedName, entry, displayStack, getPages(pages)); - } - - private static BookletPage[] getPages(BookletPage... pages){ - ArrayList allPages = new ArrayList(); - allPages.addAll(Arrays.asList(pages)); - - for(CrusherRecipe recipe : CrusherCrafting.MISC_RECIPES){ - allPages.add(new PageCrusherRecipe(allPages.size()+1, recipe).setNoText()); - } - - return allPages.toArray(new BookletPage[allPages.size()]); - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntry.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntry.java index e2e67f6bc..3fae8e481 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntry.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntry.java @@ -13,6 +13,7 @@ package de.ellpeck.actuallyadditions.mod.booklet.entry; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; +import de.ellpeck.actuallyadditions.api.booklet.internal.IEntryGui; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; import net.minecraft.util.text.TextFormatting; @@ -34,7 +35,7 @@ public class BookletEntry implements IBookletEntry{ } @Override - public List getChapters(){ + public List getAllChapters(){ return this.chapters; } @@ -64,6 +65,11 @@ public class BookletEntry implements IBookletEntry{ this.chapters.add(chapter); } + @Override + public IEntryGui createGui(){ + return null; + } + public BookletEntry setImportant(){ this.color = TextFormatting.DARK_GREEN; return this; diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryAllSearch.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryAllItems.java similarity index 56% rename from src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryAllSearch.java rename to src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryAllItems.java index 76da4e361..950180a6d 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryAllSearch.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryAllItems.java @@ -1,5 +1,5 @@ /* - * This file ("BookletEntryAllSearch.java") is part of the Actually Additions mod for Minecraft. + * This file ("BookletEntryAllItems.java") is part of the Actually Additions mod for Minecraft. * It is created and owned by Ellpeck and distributed * under the Actually Additions License to be found at * http://ellpeck.de/actaddlicense @@ -10,10 +10,9 @@ package de.ellpeck.actuallyadditions.mod.booklet.entry; -public class BookletEntryAllSearch extends BookletEntry{ +public class BookletEntryAllItems extends BookletEntry{ - public BookletEntryAllSearch(String unlocalizedName){ - super(unlocalizedName); + public BookletEntryAllItems(String identifier){ + super(identifier); } - } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/EntrySet.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/EntrySet.java deleted file mode 100644 index cb7655f55..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/EntrySet.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file ("EntrySet.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.entry; - -import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; -import de.ellpeck.actuallyadditions.api.internal.IEntrySet; -import net.minecraft.nbt.NBTTagCompound; - -public class EntrySet implements IEntrySet{ - - private BookletPage page; - private IBookletChapter chapter; - private IBookletEntry entry; - private int pageInIndex; - - public EntrySet(IBookletEntry entry){ - this(null, null, entry, 1); - } - - public EntrySet(BookletPage page, IBookletChapter chapter, IBookletEntry entry, int pageInIndex){ - this.setEntry(page, chapter, entry, pageInIndex); - } - - @Override - public void readFromNBT(NBTTagCompound compound){ - if(compound != null){ - String entryName = compound.getString("Entry"); - if(!entryName.isEmpty()){ - for(IBookletEntry entry : ActuallyAdditionsAPI.BOOKLET_ENTRIES){ - if(entryName.equals(entry.getIdentifier())){ - int indexPage = compound.getInteger("PageInIndex"); - - String chapterName = compound.getString("Chapter"); - if(!chapterName.isEmpty()){ - for(IBookletChapter chapter : entry.getChapters()){ - if(chapterName.equals(chapter.getIdentifier())){ - int page = compound.getInteger("Page"); - if(page != -1){ - this.page = chapter.getPageById(page); - this.chapter = chapter; - } - break; - } - } - } - this.entry = entry; - this.pageInIndex = indexPage; - } - } - } - } - } - - @Override - public void setEntry(BookletPage page, IBookletChapter chapter, IBookletEntry entry, int pageInIndex){ - this.page = page; - this.chapter = chapter; - this.entry = entry; - this.pageInIndex = pageInIndex; - } - - @Override - public void removeEntry(){ - this.setEntry(null, null, null, 1); - } - - @Override - public void writeToNBT(NBTTagCompound compound){ - compound.setInteger("PageInIndex", this.pageInIndex); - compound.setString("Entry", this.entry != null ? this.entry.getIdentifier() : ""); - compound.setString("Chapter", this.chapter != null ? this.chapter.getIdentifier() : ""); - compound.setInteger("Page", this.page != null ? this.page.getChapter().getPageId(this.page) : -1); - } - - @Override - public BookletPage getCurrentPage(){ - return this.page; - } - - @Override - public IBookletEntry getCurrentEntry(){ - return this.entry; - } - - @Override - public IBookletChapter getCurrentChapter(){ - return this.chapter; - } - - @Override - public int getPageInIndex(){ - return this.pageInIndex; - } - - @Override - public void setPage(BookletPage page){ - this.page = page; - } - - @Override - public void setEntry(IBookletEntry entry){ - this.entry = entry; - } - - @Override - public void setChapter(IBookletChapter chapter){ - this.chapter = chapter; - } - - @Override - public void setPageInIndex(int page){ - this.pageInIndex = page; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiBooklet.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiBooklet.java new file mode 100644 index 000000000..3ec5fbcfb --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiBooklet.java @@ -0,0 +1,87 @@ +/* + * This file ("GuiBooklet.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.gui; + +import de.ellpeck.actuallyadditions.api.booklet.internal.IBookletGui; +import de.ellpeck.actuallyadditions.mod.util.AssetUtil; +import de.ellpeck.actuallyadditions.mod.util.StringUtil; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.lwjgl.input.Keyboard; + +import java.io.IOException; +import java.util.List; + +@SideOnly(Side.CLIENT) +public class GuiBooklet extends GuiScreen implements IBookletGui{ + + public static final int BUTTONS_PER_PAGE = 12; + public static final ResourceLocation RES_LOC_GUI = AssetUtil.getBookletGuiLocation("guiBooklet"); + public static final ResourceLocation RES_LOC_GADGETS = AssetUtil.getBookletGuiLocation("guiBookletGadgets"); + + protected GuiScreen parent; + + protected int xSize; + protected int ySize; + protected int guiLeft; + protected int guiTop; + + public GuiBooklet(GuiScreen parent){ + this.parent = parent; + + this.xSize = 281; + this.ySize = 180; + } + + @Override + public void initGui(){ + super.initGui(); + + this.guiLeft = (this.width-this.xSize)/2; + this.guiTop = (this.height-this.ySize)/2; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks){ + this.mc.getTextureManager().bindTexture(RES_LOC_GUI); + drawModalRectWithCustomSizedTexture(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize, 512, 512); + + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + public boolean doesGuiPauseGame(){ + return false; + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException{ + if(this.parent != null && keyCode == Keyboard.KEY_ESCAPE){ + this.mc.displayGuiScreen(this.parent); + } + else{ + super.keyTyped(typedChar, keyCode); + } + } + + @Override + public void renderScaledAsciiString(String text, int x, int y, int color, boolean shadow, float scale){ + StringUtil.renderScaledAsciiString(this.fontRendererObj, text, x, y, color, shadow, scale); + } + + @Override + public void renderSplitScaledAsciiString(String text, int x, int y, int color, boolean shadow, float scale, int length){ + StringUtil.renderSplitScaledAsciiString(this.fontRendererObj, text, x, y, color, shadow, scale, length); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiEntry.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiEntry.java new file mode 100644 index 000000000..9b84313a7 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiEntry.java @@ -0,0 +1,48 @@ +/* + * This file ("GuiEntry.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.gui; + +import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; +import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; +import de.ellpeck.actuallyadditions.api.booklet.internal.IEntryGui; +import net.minecraft.client.gui.GuiScreen; + +public class GuiEntry extends GuiBooklet implements IEntryGui{ + + //The page in the entry. Say you have 2 more chapters than fit on one double page, then those 2 would be displayed on entryPage 1 instead. + private final int entryPage; + private final IBookletEntry entry; + + public GuiEntry(GuiScreen parent, IBookletEntry entry, int entryPage){ + super(parent); + this.entry = entry; + this.entryPage = entryPage; + } + + public GuiEntry(GuiScreen parent, IBookletEntry entry, IBookletChapter chapterForPageCalc){ + this(parent, entry, calcEntryPage(entry, chapterForPageCalc)); + } + + private static int calcEntryPage(IBookletEntry entry, IBookletChapter chapterForPageCalc){ + int index = entry.getAllChapters().indexOf(chapterForPageCalc); + return index/(BUTTONS_PER_PAGE*2); + } + + @Override + public IBookletEntry getEntry(){ + return this.entry; + } + + @Override + public int getEntryPage(){ + return this.entryPage; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiMainPage.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiMainPage.java new file mode 100644 index 000000000..dd0f9d3de --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiMainPage.java @@ -0,0 +1,41 @@ +/* + * This file ("GuiMainPage.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.gui; + +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; +import de.ellpeck.actuallyadditions.mod.booklet.button.EntryButton; +import net.minecraft.client.gui.GuiScreen; + +public class GuiMainPage extends GuiBooklet{ + + public GuiMainPage(GuiScreen parent){ + super(parent); + } + + @Override + public void initGui(){ + super.initGui(); + + for(int x = 0; x < 2; x++){ + for(int y = 0; y < BUTTONS_PER_PAGE; y++){ + int id = y+x*BUTTONS_PER_PAGE; + if(ActuallyAdditionsAPI.BOOKLET_ENTRIES.size() > id){ + IBookletEntry entry = ActuallyAdditionsAPI.BOOKLET_ENTRIES.get(id); + this.buttonList.add(new EntryButton(id, this.guiLeft+12, this.guiTop+12+y*16, 115, 10, entry.getLocalizedNameWithFormatting(), null)); + } + else{ + return; + } + } + } + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiPage.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiPage.java new file mode 100644 index 000000000..a42a7569b --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiPage.java @@ -0,0 +1,30 @@ +/* + * This file ("GuiPage.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.gui; + +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; +import de.ellpeck.actuallyadditions.api.booklet.internal.IPageGui; +import net.minecraft.client.gui.GuiScreen; + +public class GuiPage extends GuiBooklet implements IPageGui{ + + private final IBookletPage page; + + public GuiPage(GuiScreen parent, IBookletPage page){ + super(parent); + this.page = page; + } + + @Override + public IBookletPage getPage(){ + return this.page; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/misc/BookletUtils.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/misc/BookletUtils.java new file mode 100644 index 000000000..6c9d4728e --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/misc/BookletUtils.java @@ -0,0 +1,33 @@ +/* + * This file ("BookletUtils.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.misc; + +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; +import de.ellpeck.actuallyadditions.mod.util.ItemUtil; +import net.minecraft.item.ItemStack; + +public final class BookletUtils{ + + public static IBookletPage findFirstPageForStack(ItemStack stack){ + for(IBookletPage page : ActuallyAdditionsAPI.BOOKLET_PAGES_WITH_ITEM_OR_FLUID_DATA){ + ItemStack[] stacks = page.getItemStacksForPage(); + if(stacks != null && stacks.length > 0){ + for(ItemStack pageStack : stacks){ + if(ItemUtil.areItemsEqual(pageStack, stack, true)){ + return page; + } + } + } + } + return null; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiAAAchievements.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/misc/GuiAAAchievements.java similarity index 88% rename from src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiAAAchievements.java rename to src/main/java/de/ellpeck/actuallyadditions/mod/booklet/misc/GuiAAAchievements.java index b46478423..cb23c04f8 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/GuiAAAchievements.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/misc/GuiAAAchievements.java @@ -8,7 +8,7 @@ * © 2015-2016 Ellpeck */ -package de.ellpeck.actuallyadditions.mod.booklet; +package de.ellpeck.actuallyadditions.mod.booklet.misc; import de.ellpeck.actuallyadditions.mod.achievement.InitAchievements; import de.ellpeck.actuallyadditions.mod.util.ModUtil; @@ -16,10 +16,13 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.achievement.GuiAchievements; import net.minecraft.stats.StatisticsManager; import net.minecraftforge.fml.relauncher.ReflectionHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; /** * (Partially excerpted from Botania by Vazkii with permission, thanks!) */ +@SideOnly(Side.CLIENT) public class GuiAAAchievements extends GuiAchievements{ public GuiAAAchievements(GuiScreen screen, StatisticsManager statistics){ diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPageAA.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPage.java similarity index 64% rename from src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPageAA.java rename to src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPage.java index 66b1b68b5..be30a7b74 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPageAA.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPage.java @@ -10,34 +10,63 @@ package de.ellpeck.actuallyadditions.mod.booklet.page; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; +import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; +import de.ellpeck.actuallyadditions.api.booklet.internal.IPageGui; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; +import net.minecraft.item.ItemStack; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -public class BookletPageAA extends BookletPage{ +public class BookletPage implements IBookletPage{ + + protected IBookletChapter chapter; - protected final int localizationKey; protected List fluidsForPage = new ArrayList(); + protected List itemsForPage = new ArrayList(); - public BookletPageAA(int localizationKey){ + protected boolean hasNoText; + protected final HashMap textReplacements = new HashMap(); + protected final int localizationKey; + + public BookletPage(int localizationKey){ this.localizationKey = localizationKey; } @Override - public int getID(){ - return this.chapter.getPageId(this); + public ItemStack[] getItemStacksForPage(){ + return this.itemsForPage.toArray(new ItemStack[this.itemsForPage.size()]); } @Override - public String getText(){ + public FluidStack[] getFluidStacksForPage(){ + return this.fluidsForPage.toArray(new FluidStack[this.fluidsForPage.size()]); + } + + @Override + public IBookletChapter getChapter(){ + return this.chapter; + } + + @Override + public void setChapter(IBookletChapter chapter){ + this.chapter = chapter; + } + + @Override + public IPageGui createGui(){ + return null; + } + + @Override + public String getInfoText(){ if(this.hasNoText){ return null; } @@ -56,33 +85,13 @@ public class BookletPageAA extends BookletPage{ return base; } - @Override - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - - } - - @Override - public void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - - } - - @Override - public void updateScreen(int ticksElapsed){ - - } - - @Override - public FluidStack[] getFluidStacksForPage(){ - return this.fluidsForPage.toArray(new FluidStack[this.fluidsForPage.size()]); - } - - public BookletPageAA addFluidToPage(Fluid fluid){ + public BookletPage addFluidToPage(Fluid fluid){ this.fluidsForPage.add(new FluidStack(fluid, 1)); return this; } - @Override - public String getClickToSeeRecipeString(){ - return TextFormatting.GOLD+StringUtil.localize("booklet."+ModUtil.MOD_ID+".clickToSeeRecipe"); + public BookletPage addItemToPage(ItemStack stack){ + this.itemsForPage.add(stack); + return this; } -} +} \ No newline at end of file diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageButton.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageButton.java deleted file mode 100644 index b54693f5e..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageButton.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file ("PageButton.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; - -public abstract class PageButton extends PageTextOnly{ - - private GuiButton button; - - public PageButton(int id){ - super(id); - } - - @Override - public void onOpened(IBookletGui gui){ - String text = StringUtil.localize("booklet."+ModUtil.MOD_ID+".chapter."+this.chapter.getIdentifier()+".page."+this.localizationKey+".button"); - int width = Minecraft.getMinecraft().fontRendererObj.getStringWidth(text); - this.button = new GuiButton(-1239, gui.getGuiLeft()+gui.getXSize()/2-width/2-8, gui.getGuiTop()+gui.getYSize()-40, width+15, 20, text); - gui.getButtonList().add(this.button); - } - - @Override - public void onClosed(IBookletGui gui){ - gui.getButtonList().remove(this.button); - } - - @Override - public boolean onActionPerformed(IBookletGui gui, GuiButton button){ - return button == this.button && this.onAction(); - } - - public abstract boolean onAction(); -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeRecipe.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeRecipe.java deleted file mode 100644 index 83d670b9e..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeRecipe.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file ("PageCoffeeRecipe.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.api.recipe.CoffeeIngredient; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.items.InitItems; -import de.ellpeck.actuallyadditions.mod.items.metalists.TheMiscItems; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import de.ellpeck.actuallyadditions.mod.util.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public class PageCoffeeRecipe extends BookletPageAA{ - - public final CoffeeIngredient ingredient; - - public PageCoffeeRecipe(int id, CoffeeIngredient ingredient){ - super(id); - this.ingredient = ingredient; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - Minecraft.getMinecraft().getTextureManager().bindTexture(GuiBooklet.RES_LOC); - gui.drawRect(gui.getGuiLeft()+19, gui.getGuiTop()+20, 146, 94, 99, 60); - } - - @Override - @SideOnly(Side.CLIENT) - public void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - String strg = "Coffee Machine Recipe"; - Minecraft.getMinecraft().fontRendererObj.drawString(strg, gui.getGuiLeft()+gui.getXSize()/2-Minecraft.getMinecraft().fontRendererObj.getStringWidth(strg)/2, gui.getGuiTop()+10, 0); - - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+100, 115, 0, false); - } - - if(this.ingredient.maxAmplifier > 0){ - Minecraft.getMinecraft().fontRendererObj.drawString("Maximum Amplifier: "+this.ingredient.maxAmplifier, gui.getGuiLeft()+19+5, gui.getGuiTop()+20+60, 0); - } - - for(int i = 0; i < 2; i++){ - for(int j = 0; j < 4; j++){ - ItemStack stack; - int coordsOffsetX; - int coordsOffsetY; - - switch(j){ - case 0: - stack = new ItemStack(InitItems.itemMisc, 1, TheMiscItems.CUP.ordinal()); - coordsOffsetX = 39; - coordsOffsetY = 8; - break; - case 1: - stack = new ItemStack(InitItems.itemCoffeeBean); - coordsOffsetX = 5; - coordsOffsetY = 8; - break; - case 2: - stack = new ItemStack(InitItems.itemCoffee); - ActuallyAdditionsAPI.methodHandler.addEffectToStack(stack, this.ingredient); - coordsOffsetX = 39; - coordsOffsetY = 39; - break; - default: - stack = this.ingredient.ingredient; - coordsOffsetX = 82; - coordsOffsetY = 8; - break; - } - - if(stack != null){ - if(stack.getItemDamage() == Util.WILDCARD){ - stack.setItemDamage(0); - } - - boolean tooltip = i == 1; - - int xShow = gui.getGuiLeft()+19+coordsOffsetX; - int yShow = gui.getGuiTop()+20+coordsOffsetY; - if(!tooltip){ - AssetUtil.renderStackToGui(stack, xShow, yShow, 1.0F); - } - else{ - if(mouseX >= xShow && mouseX <= xShow+16 && mouseY >= yShow && mouseY <= yShow+16){ - gui.renderTooltipAndTransferButton(this, stack, mouseX, mouseY, j != 2, mousePressed); - } - } - } - } - } - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrafting.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrafting.java deleted file mode 100644 index 8f9d5163a..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrafting.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * This file ("PageCrafting.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import de.ellpeck.actuallyadditions.mod.util.Util; -import net.minecraft.client.Minecraft; -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.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.ReflectionHelper; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import net.minecraftforge.oredict.ShapedOreRecipe; -import net.minecraftforge.oredict.ShapelessOreRecipe; - -import java.util.ArrayList; -import java.util.List; - - -public class PageCrafting extends BookletPageAA{ - - private final IRecipe[] recipes; - private int recipePos; - - public PageCrafting(int id, ArrayList recipes){ - this(id, recipes.toArray(new IRecipe[recipes.size()])); - } - - public PageCrafting(int id, IRecipe... recipes){ - super(id); - this.recipes = recipes; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - if(this.recipes != null && this.recipes.length > 0 && this.recipes[this.recipePos] != null){ - Minecraft.getMinecraft().getTextureManager().bindTexture(GuiBooklet.RES_LOC); - gui.drawRect(gui.getGuiLeft()+27, gui.getGuiTop()+20, 146, 20, 99, 60); - } - } - - @Override - @SideOnly(Side.CLIENT) - public void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - IRecipe recipe = this.recipes != null && this.recipes.length > 0 ? this.recipes[this.recipePos] : null; - - if(recipe == null){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, TextFormatting.DARK_RED+StringUtil.localize("booklet."+ModUtil.MOD_ID+".recipeDisabled"), gui.getGuiLeft()+14, gui.getGuiTop()+15, 115, 0, false); - } - else{ - String strg = StringUtil.localize("booklet."+ModUtil.MOD_ID+"."+(recipe instanceof ShapedRecipes ? "shapedRecipe" : (recipe instanceof ShapelessRecipes ? "shapelessRecipe" : (recipe instanceof ShapelessOreRecipe ? "shapelessOreRecipe" : "shapedOreRecipe")))); - Minecraft.getMinecraft().fontRendererObj.drawString(strg, gui.getGuiLeft()+gui.getXSize()/2-Minecraft.getMinecraft().fontRendererObj.getStringWidth(strg)/2, gui.getGuiTop()+10, 0); - } - - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+90, 115, 0, false); - } - - if(recipe != null){ - - ItemStack[] stacks = new ItemStack[9]; - int width = 3; - int height = 3; - - if(recipe instanceof ShapedRecipes){ - ShapedRecipes shaped = (ShapedRecipes)recipe; - width = shaped.recipeWidth; - height = shaped.recipeHeight; - for(int i = 0; i < shaped.recipeItems.length; i++){ - ItemStack stack = shaped.recipeItems[i]; - if(stack != null){ - stacks[i] = stack.copy(); - } - } - } - else if(recipe instanceof ShapelessRecipes){ - ShapelessRecipes shapeless = (ShapelessRecipes)recipe; - for(int i = 0; i < shapeless.recipeItems.size(); i++){ - ItemStack stack = shapeless.recipeItems.get(i); - if(stack != null){ - stacks[i] = stack.copy(); - } - } - } - else if(recipe instanceof ShapedOreRecipe){ - ShapedOreRecipe shaped = (ShapedOreRecipe)recipe; - try{ - width = ReflectionHelper.getPrivateValue(ShapedOreRecipe.class, shaped, 4); - height = ReflectionHelper.getPrivateValue(ShapedOreRecipe.class, shaped, 5); - } - catch(Exception e){ - ModUtil.LOGGER.error("Something went wrong trying to get the Crafting Recipe in the booklet to display!", e); - } - for(int i = 0; i < shaped.getInput().length; i++){ - Object input = shaped.getInput()[i]; - if(input != null){ - ItemStack stack = input instanceof ItemStack ? (ItemStack)input : (((List)input).isEmpty() ? null : ((List)input).get(0)); - if(stack != null){ - stacks[i] = stack.copy(); - } - } - } - } - else if(recipe instanceof ShapelessOreRecipe){ - ShapelessOreRecipe shapeless = (ShapelessOreRecipe)recipe; - for(int i = 0; i < shapeless.getInput().size(); i++){ - Object input = shapeless.getInput().get(i); - ItemStack stack = input instanceof ItemStack ? (ItemStack)input : (((List)input).isEmpty() ? null : ((List)input).get(0)); - if(stack != null){ - stacks[i] = stack.copy(); - } - } - } - - int xShowOutput = gui.getGuiLeft()+27+82; - int yShowOutput = gui.getGuiTop()+20+22; - AssetUtil.renderStackToGui(recipe.getRecipeOutput(), xShowOutput, yShowOutput, 1.0F); - for(int i = 0; i < 2; i++){ - boolean tooltip = i == 1; - for(int x = 0; x < width; x++){ - for(int y = 0; y < height; y++){ - ItemStack stack = stacks[y*width+x]; - if(stack != null){ - stack.stackSize = 1; - if(stack.getItemDamage() == Util.WILDCARD){ - stack.setItemDamage(0); - } - int xShow = gui.getGuiLeft()+27+4+x*18; - int yShow = gui.getGuiTop()+20+4+y*18; - if(!tooltip){ - AssetUtil.renderStackToGui(stack, xShow, yShow, 1.0F); - } - else{ - if(mouseX >= xShow && mouseX <= xShow+16 && mouseY >= yShow && mouseY <= yShow+16){ - gui.renderTooltipAndTransferButton(this, stack, mouseX, mouseY, true, mousePressed); - } - } - } - } - } - } - if(mouseX >= xShowOutput && mouseX <= xShowOutput+16 && mouseY >= yShowOutput && mouseY <= yShowOutput+16){ - gui.renderTooltipAndTransferButton(this, recipe.getRecipeOutput(), mouseX, mouseY, false, mousePressed); - } - } - } - - @Override - @SideOnly(Side.CLIENT) - public void updateScreen(int ticksElapsed){ - if(ticksElapsed%15 == 0){ - if(this.recipePos+1 >= this.recipes.length){ - this.recipePos = 0; - } - else{ - this.recipePos++; - } - } - } - - @Override - public ItemStack[] getItemStacksForPage(){ - if(this.recipes != null && this.recipes.length > 0){ - ItemStack[] stacks = new ItemStack[this.recipes.length]; - for(int i = 0; i < this.recipes.length; i++){ - if(this.recipes[i] != null){ - ItemStack output = this.recipes[i].getRecipeOutput(); - if(output != null){ - if(!this.arePageStacksWildcard){ - stacks[i] = output; - } - else{ - ItemStack wildcardOutput = output.copy(); - wildcardOutput.setItemDamage(Util.WILDCARD); - stacks[i] = wildcardOutput; - } - } - } - } - return stacks; - } - return null; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrusherRecipe.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrusherRecipe.java deleted file mode 100644 index 27813a23c..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrusherRecipe.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file ("PageCrusherRecipe.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.api.recipe.CrusherRecipe; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import de.ellpeck.actuallyadditions.mod.util.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - - -public class PageCrusherRecipe extends BookletPageAA{ - - public final CrusherRecipe recipe; - - public PageCrusherRecipe(int id, CrusherRecipe recipe){ - super(id); - this.recipe = recipe; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - if(this.recipe != null){ - Minecraft.getMinecraft().getTextureManager().bindTexture(GuiBooklet.RES_LOC); - gui.drawRect(gui.getGuiLeft()+37, gui.getGuiTop()+20, 60, 180, 60, 60); - } - } - - @Override - @SideOnly(Side.CLIENT) - public void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - if(this.recipe == null){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, TextFormatting.DARK_RED+StringUtil.localize("booklet."+ModUtil.MOD_ID+".recipeDisabled"), gui.getGuiLeft()+14, gui.getGuiTop()+15, 115, 0, false); - } - else{ - String strg = "Crusher Recipe"; - Minecraft.getMinecraft().fontRendererObj.drawString(strg, gui.getGuiLeft()+gui.getXSize()/2-Minecraft.getMinecraft().fontRendererObj.getStringWidth(strg)/2, gui.getGuiTop()+10, 0); - } - - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+100, 115, 0, false); - } - - if(this.recipe != null){ - if(this.recipe.outputTwoChance > 0){ - Minecraft.getMinecraft().fontRendererObj.drawString(this.recipe.outputTwoChance+"%", gui.getGuiLeft()+37+62, gui.getGuiTop()+20+33, 0); - } - - for(int i = 0; i < 2; i++){ - for(int j = 0; j < 3; j++){ - ItemStack stack; - switch(j){ - case 0: - stack = this.recipe.inputStack; - break; - case 1: - stack = this.recipe.outputOneStack; - break; - default: - stack = this.recipe.outputTwoStack; - break; - } - - if(stack != null){ - if(stack.getItemDamage() == Util.WILDCARD){ - stack.setItemDamage(0); - } - - boolean tooltip = i == 1; - - int xShow = gui.getGuiLeft()+37+(j == 0 ? 1 : (j == 1 ? 43 : (j == 2 ? 43 : 0))); - int yShow = gui.getGuiTop()+20+(j == 0 ? 21 : (j == 1 ? 11 : (j == 2 ? 29 : 0))); - if(!tooltip){ - AssetUtil.renderStackToGui(stack, xShow, yShow, 1.0F); - } - else{ - if(mouseX >= xShow && mouseX <= xShow+16 && mouseY >= yShow && mouseY <= yShow+16){ - gui.renderTooltipAndTransferButton(this, stack, mouseX, mouseY, j == 0, mousePressed); - } - } - } - } - } - } - } - - @Override - public ItemStack[] getItemStacksForPage(){ - return this.recipe == null ? new ItemStack[0] : new ItemStack[]{this.recipe.outputOneStack, this.recipe.outputTwoStack}; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageEmpowerer.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageEmpowerer.java deleted file mode 100644 index 8740a432a..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageEmpowerer.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file ("PageEmpowerer.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.api.recipe.EmpowererRecipe; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import de.ellpeck.actuallyadditions.mod.util.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.ArrayList; - -public class PageEmpowerer extends BookletPageAA{ - - private final EmpowererRecipe[] recipes; - private int recipePos; - - public PageEmpowerer(int id, ArrayList recipes){ - this(id, recipes.toArray(new EmpowererRecipe[recipes.size()])); - } - - public PageEmpowerer(int id, EmpowererRecipe... recipes){ - super(id); - this.recipes = recipes; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - if(this.recipes[this.recipePos] != null){ - Minecraft.getMinecraft().getTextureManager().bindTexture(GuiBooklet.RES_LOC_ADDON); - gui.drawRect(gui.getGuiLeft()+22, gui.getGuiTop()+20, 0, 0, 94, 58); - } - } - - @Override - @SideOnly(Side.CLIENT) - public void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - EmpowererRecipe recipe = this.recipes[this.recipePos]; - if(recipe == null){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, TextFormatting.DARK_RED+StringUtil.localize("booklet."+ModUtil.MOD_ID+".recipeDisabled"), gui.getGuiLeft()+14, gui.getGuiTop()+15, 115, 0, false); - } - else{ - String strg = "Empowerer"; - Minecraft.getMinecraft().fontRendererObj.drawString(strg, gui.getGuiLeft()+gui.getXSize()/2-Minecraft.getMinecraft().fontRendererObj.getStringWidth(strg)/2, gui.getGuiTop()+10, 0); - } - - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+100, 115, 0, false); - } - - if(recipe != null){ - for(int i = 0; i < 2; i++){ - for(int count = 0; count < 6; count++){ - ItemStack stack; - int x; - int y; - switch(count){ - case 0: - stack = recipe.input; - x = 21; - y = 21; - break; - case 1: - stack = recipe.modifier1; - x = 21; - y = 1; - break; - case 2: - stack = recipe.modifier2; - x = 41; - y = 21; - break; - case 3: - stack = recipe.modifier3; - x = 21; - y = 41; - break; - case 4: - stack = recipe.modifier4; - x = 1; - y = 21; - break; - default: - stack = recipe.output; - x = 77; - y = 21; - break; - } - - if(stack.getItemDamage() == Util.WILDCARD){ - stack.setItemDamage(0); - } - - int xShow = gui.getGuiLeft()+22+x; - int yShow = gui.getGuiTop()+20+y; - if(i != 1){ - AssetUtil.renderStackToGui(stack, xShow, yShow, 1.0F); - } - else{ - if(mouseX >= xShow && mouseX <= xShow+16 && mouseY >= yShow && mouseY <= yShow+16){ - gui.renderTooltipAndTransferButton(this, stack, mouseX, mouseY, x != 5, mousePressed); - } - } - } - } - } - } - - @Override - @SideOnly(Side.CLIENT) - public void updateScreen(int ticksElapsed){ - if(ticksElapsed%15 == 0){ - if(this.recipePos+1 >= this.recipes.length){ - this.recipePos = 0; - } - else{ - this.recipePos++; - } - } - } - - @Override - public ItemStack[] getItemStacksForPage(){ - if(this.recipes != null){ - ArrayList stacks = new ArrayList(); - for(EmpowererRecipe recipe : this.recipes){ - if(recipe != null){ - stacks.add(recipe.output); - } - } - return stacks.toArray(new ItemStack[stacks.size()]); - } - return null; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageFurnace.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageFurnace.java deleted file mode 100644 index 72ee91c1a..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageFurnace.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file ("PageFurnace.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import de.ellpeck.actuallyadditions.mod.util.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.FurnaceRecipes; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.Map; - -public class PageFurnace extends BookletPageAA{ - - private final ItemStack result; - private final ItemStack input; - - public PageFurnace(int id, ItemStack result){ - this(id, null, result); - } - - public PageFurnace(int id, ItemStack input, ItemStack result){ - super(id); - this.result = result; - this.input = input; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - if(this.input != null || this.getInputForOutput(this.result) != null){ - Minecraft.getMinecraft().getTextureManager().bindTexture(GuiBooklet.RES_LOC); - gui.drawRect(gui.getGuiLeft()+37, gui.getGuiTop()+20, 0, 180, 60, 60); - } - } - - @Override - @SideOnly(Side.CLIENT) - public void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - ItemStack input = this.input != null ? this.input : this.getInputForOutput(this.result); - if(input == null){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, TextFormatting.DARK_RED+StringUtil.localize("booklet."+ModUtil.MOD_ID+".recipeDisabled"), gui.getGuiLeft()+14, gui.getGuiTop()+15, 115, 0, false); - } - else{ - String strg = "Furnace Recipe"; - Minecraft.getMinecraft().fontRendererObj.drawString(strg, gui.getGuiLeft()+gui.getXSize()/2-Minecraft.getMinecraft().fontRendererObj.getStringWidth(strg)/2, gui.getGuiTop()+10, 0); - } - - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+100, 115, 0, false); - } - - if(input != null){ - for(int i = 0; i < 2; i++){ - for(int x = 0; x < 2; x++){ - ItemStack stack = x == 0 ? input : this.result; - if(stack.getItemDamage() == Util.WILDCARD){ - stack.setItemDamage(0); - } - boolean tooltip = i == 1; - - int xShow = gui.getGuiLeft()+37+1+x*42; - int yShow = gui.getGuiTop()+20+21; - if(!tooltip){ - AssetUtil.renderStackToGui(stack, xShow, yShow, 1.0F); - } - else{ - if(mouseX >= xShow && mouseX <= xShow+16 && mouseY >= yShow && mouseY <= yShow+16){ - gui.renderTooltipAndTransferButton(this, stack, mouseX, mouseY, x == 0, mousePressed); - } - } - } - } - } - } - - @Override - public ItemStack[] getItemStacksForPage(){ - return this.result == null ? new ItemStack[0] : new ItemStack[]{this.result}; - } - - private ItemStack getInputForOutput(ItemStack output){ - for(Map.Entry o : FurnaceRecipes.instance().getSmeltingList().entrySet()){ - ItemStack stack = (ItemStack)(o).getValue(); - if(stack.isItemEqual(output)){ - return (ItemStack)(o).getKey(); - } - } - return null; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageLinkButton.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageLinkButton.java deleted file mode 100644 index f062290df..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageLinkButton.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file ("PageLinkButton.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; - -public class PageLinkButton extends PageButton{ - - private final String link; - - public PageLinkButton(int id, String link){ - super(id); - this.link = link; - } - - @Override - public boolean onAction(){ - BookletUtils.openBrowser(this.link); - return true; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PagePicture.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PagePicture.java deleted file mode 100644 index dd768545b..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PagePicture.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file ("PagePicture.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public class PagePicture extends PageTextOnly{ - - private final ResourceLocation resLoc; - private final int textStartY; - - public PagePicture(int id, String resLocName, int textStartY){ - this(id, AssetUtil.getBookletGuiLocation(resLocName), textStartY); - } - - public PagePicture(int id, ResourceLocation resLoc, int textStartY){ - super(id); - this.textStartY = textStartY; - this.resLoc = resLoc; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - GlStateManager.enableBlend(); - Minecraft.getMinecraft().getTextureManager().bindTexture(this.resLoc); - gui.drawRect(gui.getGuiLeft(), gui.getGuiTop(), 0, 0, gui.getXSize(), gui.getYSize()); - GlStateManager.disableBlend(); - - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+this.textStartY, 115, 0, false); - } - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageReconstructor.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageReconstructor.java deleted file mode 100644 index add3c82b0..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageReconstructor.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file ("PageReconstructor.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.api.recipe.LensConversionRecipe; -import de.ellpeck.actuallyadditions.mod.blocks.InitBlocks; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; -import de.ellpeck.actuallyadditions.mod.util.ModUtil; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import de.ellpeck.actuallyadditions.mod.util.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.ArrayList; - -public class PageReconstructor extends BookletPageAA{ - - private final LensConversionRecipe[] recipes; - private int recipePos; - - public PageReconstructor(int id, ArrayList recipes){ - this(id, recipes.toArray(new LensConversionRecipe[recipes.size()])); - } - - public PageReconstructor(int id, LensConversionRecipe... recipes){ - super(id); - this.recipes = recipes; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - if(this.recipes[this.recipePos] != null){ - Minecraft.getMinecraft().getTextureManager().bindTexture(GuiBooklet.RES_LOC); - gui.drawRect(gui.getGuiLeft()+37, gui.getGuiTop()+20, 188, 154, 60, 60); - } - } - - @Override - @SideOnly(Side.CLIENT) - public void render(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - LensConversionRecipe recipe = this.recipes[this.recipePos]; - if(recipe == null){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, TextFormatting.DARK_RED+StringUtil.localize("booklet."+ModUtil.MOD_ID+".recipeDisabled"), gui.getGuiLeft()+14, gui.getGuiTop()+15, 115, 0, false); - } - else{ - String strg = "Atomic Reconstructor"; - Minecraft.getMinecraft().fontRendererObj.drawString(strg, gui.getGuiLeft()+gui.getXSize()/2-Minecraft.getMinecraft().fontRendererObj.getStringWidth(strg)/2, gui.getGuiTop()+10, 0); - Minecraft.getMinecraft().fontRendererObj.drawString(recipe.energyUse+" RF", gui.getGuiLeft()+80, gui.getGuiTop()+30, 0, false); - } - - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+100, 115, 0, false); - } - - if(recipe != null){ - AssetUtil.renderStackToGui(new ItemStack(InitBlocks.blockAtomicReconstructor), gui.getGuiLeft()+37+22, gui.getGuiTop()+20+21, 1.0F); - for(int i = 0; i < 2; i++){ - for(int x = 0; x < 2; x++){ - ItemStack stack = x == 0 ? recipe.inputStack : recipe.outputStack; - - if(stack.getItemDamage() == Util.WILDCARD){ - stack.setItemDamage(0); - } - boolean tooltip = i == 1; - - int xShow = gui.getGuiLeft()+37+1+x*42; - int yShow = gui.getGuiTop()+20+21; - if(!tooltip){ - AssetUtil.renderStackToGui(stack, xShow, yShow, 1.0F); - } - else{ - if(mouseX >= xShow && mouseX <= xShow+16 && mouseY >= yShow && mouseY <= yShow+16){ - gui.renderTooltipAndTransferButton(this, stack, mouseX, mouseY, x == 0, mousePressed); - } - } - } - } - } - } - - @Override - @SideOnly(Side.CLIENT) - public void updateScreen(int ticksElapsed){ - if(ticksElapsed%15 == 0){ - if(this.recipePos+1 >= this.recipes.length){ - this.recipePos = 0; - } - else{ - this.recipePos++; - } - } - } - - @Override - public ItemStack[] getItemStacksForPage(){ - if(this.recipes != null){ - ArrayList stacks = new ArrayList(); - for(LensConversionRecipe recipe : this.recipes){ - if(recipe != null){ - stacks.add(recipe.outputStack); - } - } - return stacks.toArray(new ItemStack[stacks.size()]); - } - return null; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTextOnly.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTextOnly.java deleted file mode 100644 index 61d7944e6..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTextOnly.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file ("PageTextOnly.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.booklet.page; - -import de.ellpeck.actuallyadditions.api.internal.IBookletGui; -import de.ellpeck.actuallyadditions.mod.util.StringUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public class PageTextOnly extends BookletPageAA{ - - private ItemStack[] stacks; - - public PageTextOnly(int id){ - super(id); - } - - public PageTextOnly setStacks(ItemStack... stacks){ - this.stacks = stacks; - return this; - } - - @Override - @SideOnly(Side.CLIENT) - public void renderPre(IBookletGui gui, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed){ - String text = gui.getCurrentEntrySet().getCurrentPage().getText(); - if(text != null && !text.isEmpty()){ - StringUtil.drawSplitString(Minecraft.getMinecraft().fontRendererObj, text, gui.getGuiLeft()+14, gui.getGuiTop()+9, 115, 0, false); - } - } - - @Override - public ItemStack[] getItemStacksForPage(){ - return this.stacks == null ? new ItemStack[0] : this.stacks; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java b/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java index 86fa93e6e..ab6cb9d63 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java @@ -147,7 +147,6 @@ public class CreativeTab extends CreativeTabs{ this.add(InitBlocks.blockTreasureChest); this.add(InitBlocks.blockBlackLotus); - this.add(InitBlocks.blockBookletStand); this.add(InitItems.itemBag); this.add(InitItems.itemVoidBag); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/GuiHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/GuiHandler.java index b293c26bf..b62c92d05 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/GuiHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/GuiHandler.java @@ -11,8 +11,8 @@ package de.ellpeck.actuallyadditions.mod.inventory; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBookletStand; +import de.ellpeck.actuallyadditions.mod.booklet.gui.GuiBooklet; +import de.ellpeck.actuallyadditions.mod.booklet.gui.GuiMainPage; import de.ellpeck.actuallyadditions.mod.inventory.gui.*; import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase; import de.ellpeck.actuallyadditions.mod.util.ModUtil; @@ -169,15 +169,13 @@ public class GuiHandler implements IGuiHandler{ case CLOUD: return new GuiSmileyCloud(tile, x, y, z, world); case BOOK: - return new GuiBooklet(null, true, true); + return new GuiMainPage(null); case DIRECTIONAL_BREAKER: return new GuiDirectionalBreaker(player.inventory, tile); case RANGED_COLLECTOR: return new GuiRangedCollector(player.inventory, tile, x, y, z, world); case MINER: return new GuiMiner(player.inventory, tile); - case BOOK_STAND: - return new GuiBookletStand(tile); case LASER_RELAY_ITEM_WHITELIST: return new GuiLaserRelayItemWhitelist(player.inventory, tile); case BAG: @@ -223,7 +221,6 @@ public class GuiHandler implements IGuiHandler{ DIRECTIONAL_BREAKER, RANGED_COLLECTOR, MINER, - BOOK_STAND, LASER_RELAY_ITEM_WHITELIST, FILTER(false), BAG(false), diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/TexturedButton.java b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/TexturedButton.java similarity index 75% rename from src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/TexturedButton.java rename to src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/TexturedButton.java index d106deb9e..419c45677 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/TexturedButton.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/TexturedButton.java @@ -8,12 +8,12 @@ * © 2015-2016 Ellpeck */ -package de.ellpeck.actuallyadditions.mod.booklet.button; +package de.ellpeck.actuallyadditions.mod.inventory.gui; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -23,18 +23,20 @@ import java.util.List; @SideOnly(Side.CLIENT) public class TexturedButton extends GuiButton{ + private final ResourceLocation resLoc; public final List textList = new ArrayList(); public int texturePosX; public int texturePosY; - public TexturedButton(int id, int x, int y, int texturePosX, int texturePosY, int width, int height){ - this(id, x, y, texturePosX, texturePosY, width, height, new ArrayList()); + public TexturedButton(ResourceLocation resLoc, int id, int x, int y, int texturePosX, int texturePosY, int width, int height){ + this(resLoc, id, x, y, texturePosX, texturePosY, width, height, new ArrayList()); } - public TexturedButton(int id, int x, int y, int texturePosX, int texturePosY, int width, int height, List hoverTextList){ + public TexturedButton(ResourceLocation resLoc, int id, int x, int y, int texturePosX, int texturePosY, int width, int height, List hoverTextList){ super(id, x, y, width, height, ""); this.texturePosX = texturePosX; this.texturePosY = texturePosY; + this.resLoc = resLoc; this.textList.addAll(hoverTextList); } @@ -46,7 +48,7 @@ public class TexturedButton extends GuiButton{ @Override public void drawButton(Minecraft minecraft, int x, int y){ if(this.visible){ - minecraft.getTextureManager().bindTexture(GuiBooklet.RES_LOC); + minecraft.getTextureManager().bindTexture(this.resLoc); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.hovered = x >= this.xPosition && y >= this.yPosition && x < this.xPosition+this.width && y < this.yPosition+this.height; int k = this.getHoverState(this.hovered); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemBooklet.java b/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemBooklet.java index c20384488..e64e31f01 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemBooklet.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemBooklet.java @@ -10,14 +10,11 @@ package de.ellpeck.actuallyadditions.mod.items; -import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.achievement.TheAchievements; import de.ellpeck.actuallyadditions.mod.blocks.IHudDisplay; -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.booklet.entry.EntrySet; +import de.ellpeck.actuallyadditions.mod.booklet.misc.BookletUtils; import de.ellpeck.actuallyadditions.mod.inventory.GuiHandler; import de.ellpeck.actuallyadditions.mod.items.base.ItemBase; import de.ellpeck.actuallyadditions.mod.util.AssetUtil; @@ -38,15 +35,14 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; public class ItemBooklet extends ItemBase implements IHudDisplay{ - @SideOnly(Side.CLIENT) - public static EntrySet forcedEntry; + //TODO Fix this + //@SideOnly(Side.CLIENT) + //public static EntrySet forcedEntry; public ItemBooklet(String name){ super(name); @@ -61,10 +57,10 @@ public class ItemBooklet extends ItemBase implements IHudDisplay{ IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); ItemStack blockStack = new ItemStack(block, 1, block.getMetaFromState(state)); - BookletPage page = BookletUtils.getFirstPageForStack(blockStack); + IBookletPage page = BookletUtils.findFirstPageForStack(blockStack); if(page != null){ if(world.isRemote){ - forcedEntry = new EntrySet(page, page.getChapter(), page.getChapter().getEntry(), ActuallyAdditionsAPI.BOOKLET_ENTRIES.indexOf(page.getChapter().getEntry())/GuiBooklet.CHAPTER_BUTTONS_AMOUNT+1); + //forcedEntry = new EntrySet(page, page.getChapter(), page.getChapter().getEntry(), ActuallyAdditionsAPI.BOOKLET_ENTRIES.indexOf(page.getChapter().getEntry())/GuiBooklet.CHAPTER_BUTTONS_AMOUNT+1); } this.onItemRightClick(stack, world, player, hand); return EnumActionResult.SUCCESS; @@ -110,10 +106,10 @@ public class ItemBooklet extends ItemBase implements IHudDisplay{ ItemStack blockStack = new ItemStack(block, 1, block.getMetaFromState(state)); int height = resolution.getScaledHeight()/5*3; if(player.isSneaking()){ - BookletPage page = BookletUtils.getFirstPageForStack(blockStack); + IBookletPage page = BookletUtils.findFirstPageForStack(blockStack); if(page != null){ String strg1 = page.getChapter().getLocalizedName(); - String strg2 = "Page "+page.getID(); + String strg2 = "Page "+page.getChapter().getPageNum(page); String strg3 = "Right-Click to open..."; AssetUtil.renderStackToGui(page.getChapter().getDisplayItemStack() != null ? page.getChapter().getDisplayItemStack() : new ItemStack(InitItems.itemBooklet), resolution.getScaledWidth()/2-10, height+41, 1F); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/RecipeWrapperWithButton.java b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/RecipeWrapperWithButton.java index dad6dcf89..86e6fa0f0 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/RecipeWrapperWithButton.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/RecipeWrapperWithButton.java @@ -10,11 +10,9 @@ package de.ellpeck.actuallyadditions.mod.jei; -import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; -import de.ellpeck.actuallyadditions.mod.booklet.GuiBooklet; -import de.ellpeck.actuallyadditions.mod.booklet.button.TexturedButton; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; +import de.ellpeck.actuallyadditions.mod.booklet.gui.GuiBooklet; +import de.ellpeck.actuallyadditions.mod.inventory.gui.TexturedButton; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; import mezz.jei.api.recipe.BlankRecipeWrapper; @@ -29,7 +27,7 @@ public abstract class RecipeWrapperWithButton extends BlankRecipeWrapper{ protected final TexturedButton theButton; public RecipeWrapperWithButton(){ - this.theButton = new TexturedButton(23782, this.getButtonX(), this.getButtonY(), 146, 154, 20, 20); + this.theButton = new TexturedButton(GuiBooklet.RES_LOC_GADGETS, 23782, this.getButtonX(), this.getButtonY(), 0, 0, 20, 20); } public abstract int getButtonX(); @@ -41,19 +39,20 @@ public abstract class RecipeWrapperWithButton extends BlankRecipeWrapper{ if(this.theButton.mousePressed(minecraft, mouseX, mouseY)){ this.theButton.playPressSound(minecraft.getSoundHandler()); - BookletPage page = this.getPage(); + IBookletPage page = this.getPage(); if(page != null){ - GuiBooklet book = new GuiBooklet(Minecraft.getMinecraft().currentScreen, false, true); + //TODO Fix this + /*GuiBooklet book = new GuiBooklet(Minecraft.getMinecraft().currentScreen, false, true); Minecraft.getMinecraft().displayGuiScreen(book); BookletUtils.openIndexEntry(book, page.getChapter().getEntry(), ActuallyAdditionsAPI.BOOKLET_ENTRIES.indexOf(page.getChapter().getEntry())/GuiBooklet.CHAPTER_BUTTONS_AMOUNT+1, true); - BookletUtils.openChapter(book, page.getChapter(), page); + BookletUtils.openChapter(book, page.getChapter(), page);*/ return true; } } return false; } - public abstract BookletPage getPage(); + public abstract IBookletPage getPage(); @Override public void drawInfo(Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY){ diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeHandler.java index ebb7b650e..0d7626720 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeHandler.java @@ -10,20 +10,20 @@ package de.ellpeck.actuallyadditions.mod.jei.booklet; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import mezz.jei.api.recipe.IRecipeHandler; import mezz.jei.api.recipe.IRecipeWrapper; -public class BookletRecipeHandler implements IRecipeHandler{ +public class BookletRecipeHandler implements IRecipeHandler{ @Override public Class getRecipeClass(){ - return BookletPage.class; + return IBookletPage.class; } @Override - public String getRecipeCategoryUid(BookletPage recipe){ + public String getRecipeCategoryUid(IBookletPage recipe){ return this.getRecipeCategoryUid(); } @@ -33,12 +33,12 @@ public class BookletRecipeHandler implements IRecipeHandler{ } @Override - public IRecipeWrapper getRecipeWrapper(BookletPage recipe){ + public IRecipeWrapper getRecipeWrapper(IBookletPage recipe){ return new BookletRecipeWrapper(recipe); } @Override - public boolean isRecipeValid(BookletPage recipe){ + public boolean isRecipeValid(IBookletPage recipe){ return true; } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeWrapper.java b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeWrapper.java index 469b95f71..19e2cc1cc 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeWrapper.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/booklet/BookletRecipeWrapper.java @@ -10,9 +10,8 @@ package de.ellpeck.actuallyadditions.mod.jei.booklet; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.mod.booklet.page.PagePicture; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.mod.jei.RecipeWrapperWithButton; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; @@ -27,9 +26,9 @@ import java.util.List; public class BookletRecipeWrapper extends RecipeWrapperWithButton{ - public final BookletPage thePage; + public final IBookletPage thePage; - public BookletRecipeWrapper(BookletPage page){ + public BookletRecipeWrapper(IBookletPage page){ this.thePage = page; } @@ -51,13 +50,13 @@ public class BookletRecipeWrapper extends RecipeWrapperWithButton{ int maxLines = 4; IBookletChapter chapter = this.thePage.getChapter(); - String aText = (chapter.getPages()[0] instanceof PagePicture && chapter.getPages().length > 1 ? chapter.getPages()[1] : chapter.getPages()[0]).getText(); + String aText = chapter.getAllPages()[0].getInfoText(); List text = minecraft.fontRendererObj.listFormattedStringToWidth(aText != null ? aText : TextFormatting.DARK_RED+StringUtil.localize("container.nei."+ModUtil.MOD_ID+".booklet.noText"), 150); for(int i = 0; i < Math.min(maxLines, text.size()); i++){ minecraft.fontRendererObj.drawString(text.get(i)+(i == maxLines-1 && text.size() > maxLines ? TextFormatting.RESET+""+TextFormatting.BLACK+"..." : ""), 0, 16+25+i*(minecraft.fontRendererObj.FONT_HEIGHT+1), 0, false); } minecraft.fontRendererObj.drawString(TextFormatting.ITALIC+chapter.getLocalizedName(), 25, 85, 0, false); - minecraft.fontRendererObj.drawString(TextFormatting.ITALIC+"Page "+this.thePage.getID(), 25, 95, 0, false); + minecraft.fontRendererObj.drawString(TextFormatting.ITALIC+"Page "+chapter.getPageNum(this.thePage), 25, 95, 0, false); super.drawInfo(minecraft, recipeWidth, recipeHeight, mouseX, mouseY); } @@ -78,7 +77,7 @@ public class BookletRecipeWrapper extends RecipeWrapperWithButton{ } @Override - public BookletPage getPage(){ + public IBookletPage getPage(){ return this.thePage; } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/coffee/CoffeeMachineRecipeWrapper.java b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/coffee/CoffeeMachineRecipeWrapper.java index f5401654a..9438e09d8 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/coffee/CoffeeMachineRecipeWrapper.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/coffee/CoffeeMachineRecipeWrapper.java @@ -11,10 +11,10 @@ package de.ellpeck.actuallyadditions.mod.jei.coffee; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.api.recipe.CoffeeIngredient; import de.ellpeck.actuallyadditions.mod.blocks.InitBlocks; -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; +import de.ellpeck.actuallyadditions.mod.booklet.misc.BookletUtils; import de.ellpeck.actuallyadditions.mod.items.InitItems; import de.ellpeck.actuallyadditions.mod.items.metalists.TheMiscItems; import de.ellpeck.actuallyadditions.mod.jei.RecipeWrapperWithButton; @@ -82,7 +82,7 @@ public class CoffeeMachineRecipeWrapper extends RecipeWrapperWithButton{ } @Override - public BookletPage getPage(){ - return BookletUtils.getFirstPageForStack(new ItemStack(InitBlocks.blockCoffeeMachine)); + public IBookletPage getPage(){ + return BookletUtils.findFirstPageForStack(new ItemStack(InitBlocks.blockCoffeeMachine)); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/crusher/CrusherRecipeWrapper.java b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/crusher/CrusherRecipeWrapper.java index 33fb9c309..0bb52c6d2 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/crusher/CrusherRecipeWrapper.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/crusher/CrusherRecipeWrapper.java @@ -10,19 +10,17 @@ package de.ellpeck.actuallyadditions.mod.jei.crusher; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.api.recipe.CrusherRecipe; import de.ellpeck.actuallyadditions.mod.blocks.InitBlocks; -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; +import de.ellpeck.actuallyadditions.mod.booklet.misc.BookletUtils; import de.ellpeck.actuallyadditions.mod.jei.RecipeWrapperWithButton; import de.ellpeck.actuallyadditions.mod.util.StringUtil; import mezz.jei.api.ingredients.IIngredients; import net.minecraft.client.Minecraft; import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class CrusherRecipeWrapper extends RecipeWrapperWithButton{ @@ -70,7 +68,7 @@ public class CrusherRecipeWrapper extends RecipeWrapperWithButton{ } @Override - public BookletPage getPage(){ - return BookletUtils.getFirstPageForStack(new ItemStack(InitBlocks.blockGrinder)); + public IBookletPage getPage(){ + return BookletUtils.findFirstPageForStack(new ItemStack(InitBlocks.blockGrinder)); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/empowerer/EmpowererRecipeWrapper.java b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/empowerer/EmpowererRecipeWrapper.java index 903fe5572..10824b361 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/empowerer/EmpowererRecipeWrapper.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/empowerer/EmpowererRecipeWrapper.java @@ -10,20 +10,15 @@ package de.ellpeck.actuallyadditions.mod.jei.empowerer; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.api.recipe.EmpowererRecipe; import de.ellpeck.actuallyadditions.mod.blocks.InitBlocks; -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; +import de.ellpeck.actuallyadditions.mod.booklet.misc.BookletUtils; import de.ellpeck.actuallyadditions.mod.jei.RecipeWrapperWithButton; import mezz.jei.api.ingredients.IIngredients; import net.minecraft.client.Minecraft; import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.List; public class EmpowererRecipeWrapper extends RecipeWrapperWithButton{ @@ -55,7 +50,7 @@ public class EmpowererRecipeWrapper extends RecipeWrapperWithButton{ } @Override - public BookletPage getPage(){ - return BookletUtils.getFirstPageForStack(new ItemStack(InitBlocks.blockEmpowerer)); + public IBookletPage getPage(){ + return BookletUtils.findFirstPageForStack(new ItemStack(InitBlocks.blockEmpowerer)); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/reconstructor/ReconstructorRecipeWrapper.java b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/reconstructor/ReconstructorRecipeWrapper.java index 31a9e563a..b0c5bfea3 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/jei/reconstructor/ReconstructorRecipeWrapper.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/jei/reconstructor/ReconstructorRecipeWrapper.java @@ -10,19 +10,14 @@ package de.ellpeck.actuallyadditions.mod.jei.reconstructor; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.api.recipe.LensConversionRecipe; import de.ellpeck.actuallyadditions.mod.blocks.InitBlocks; -import de.ellpeck.actuallyadditions.mod.booklet.BookletUtils; +import de.ellpeck.actuallyadditions.mod.booklet.misc.BookletUtils; import de.ellpeck.actuallyadditions.mod.jei.RecipeWrapperWithButton; import mezz.jei.api.ingredients.IIngredients; import net.minecraft.client.Minecraft; import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; public class ReconstructorRecipeWrapper extends RecipeWrapperWithButton{ @@ -60,7 +55,7 @@ public class ReconstructorRecipeWrapper extends RecipeWrapperWithButton{ } @Override - public BookletPage getPage(){ - return BookletUtils.getFirstPageForStack(new ItemStack(InitBlocks.blockAtomicReconstructor)); + public IBookletPage getPage(){ + return BookletUtils.findFirstPageForStack(new ItemStack(InitBlocks.blockAtomicReconstructor)); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/misc/MethodHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/misc/MethodHandler.java index 98310ab2c..65464758b 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/misc/MethodHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/misc/MethodHandler.java @@ -11,18 +11,10 @@ package de.ellpeck.actuallyadditions.mod.misc; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; -import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; import de.ellpeck.actuallyadditions.api.internal.IAtomicReconstructor; import de.ellpeck.actuallyadditions.api.internal.IMethodHandler; import de.ellpeck.actuallyadditions.api.recipe.CoffeeIngredient; import de.ellpeck.actuallyadditions.api.recipe.LensConversionRecipe; -import de.ellpeck.actuallyadditions.mod.booklet.chapter.BookletChapter; -import de.ellpeck.actuallyadditions.mod.booklet.page.PageCrafting; -import de.ellpeck.actuallyadditions.mod.booklet.page.PageFurnace; -import de.ellpeck.actuallyadditions.mod.booklet.page.PagePicture; -import de.ellpeck.actuallyadditions.mod.booklet.page.PageTextOnly; import de.ellpeck.actuallyadditions.mod.items.lens.LensRecipeHandler; import de.ellpeck.actuallyadditions.mod.recipe.CrusherRecipeRegistry; import net.minecraft.block.Block; @@ -212,31 +204,6 @@ public class MethodHandler implements IMethodHandler{ return false; } - @Override - public BookletPage generateTextPage(int id){ - return new PageTextOnly(id); - } - - @Override - public BookletPage generatePicturePage(int id, ResourceLocation resLoc, int textStartY){ - return new PagePicture(id, resLoc, textStartY); - } - - @Override - public BookletPage generateCraftingPage(int id, IRecipe... recipes){ - return new PageCrafting(id, recipes); - } - - @Override - public BookletPage generateFurnacePage(int id, ItemStack input, ItemStack result){ - return new PageFurnace(id, input, result); - } - - @Override - public IBookletChapter generateBookletChapter(String identifier, IBookletEntry entry, ItemStack displayStack, BookletPage... pages){ - return new BookletChapter(identifier, entry, displayStack, pages); - } - @Override public boolean addCrusherRecipes(List inputs, List outputOnes, int outputOneAmounts, List outputTwos, int outputTwoAmounts, int outputTwoChance){ boolean hasWorkedOnce = false; diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java index cf030a152..9d5d031dc 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java @@ -15,7 +15,6 @@ import de.ellpeck.actuallyadditions.mod.network.gui.IButtonReactor; import de.ellpeck.actuallyadditions.mod.network.gui.INumberReactor; import de.ellpeck.actuallyadditions.mod.network.gui.IStringReactor; import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase; -import de.ellpeck.actuallyadditions.mod.tile.TileEntityBookletStand; import de.ellpeck.actuallyadditions.mod.util.AssetUtil; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import net.minecraft.client.Minecraft; @@ -125,23 +124,6 @@ public final class PacketHandler{ } }; public static SimpleNetworkWrapper theNetwork; - public static final IDataHandler BOOKLET_STAND_BUTTON_HANDLER = new IDataHandler(){ - @Override - public void handleData(NBTTagCompound compound){ - World world = DimensionManager.getWorld(compound.getInteger("WorldID")); - TileEntity tile = world.getTileEntity(new BlockPos(compound.getInteger("X"), compound.getInteger("Y"), compound.getInteger("Z"))); - EntityPlayer player = (EntityPlayer)world.getEntityByID(compound.getInteger("PlayerID")); - - if(player != null && tile instanceof TileEntityBookletStand){ - TileEntityBookletStand stand = (TileEntityBookletStand)tile; - if(player.getName() != null && player.getName().equalsIgnoreCase(stand.assignedPlayer)){ - stand.assignedEntry.readFromNBT(compound.getCompoundTag("EntrySet")); - stand.markDirty(); - stand.sendUpdate(); - } - } - } - }; public static final IDataHandler CHANGE_PLAYER_DATA_HANDLER = new IDataHandler(){ @Override public void handleData(NBTTagCompound compound){ @@ -166,7 +148,6 @@ public final class PacketHandler{ DATA_HANDLERS.add(PARTICLE_HANDLER); DATA_HANDLERS.add(TILE_ENTITY_HANDLER); - DATA_HANDLERS.add(BOOKLET_STAND_BUTTON_HANDLER); DATA_HANDLERS.add(GUI_BUTTON_TO_TILE_HANDLER); DATA_HANDLERS.add(GUI_STRING_TO_TILE_HANDLER); DATA_HANDLERS.add(GUI_NUMBER_TO_TILE_HANDLER); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java index 43b8a2cc4..f6f598db4 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java @@ -12,9 +12,9 @@ package de.ellpeck.actuallyadditions.mod.proxy; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; -import de.ellpeck.actuallyadditions.api.booklet.BookletPage; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; +import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.mod.blocks.render.*; import de.ellpeck.actuallyadditions.mod.config.values.ConfigBoolValues; import de.ellpeck.actuallyadditions.mod.entity.InitEntities; @@ -70,16 +70,17 @@ public class ClientProxy implements IProxy{ bookletCharCount += entry.getLocalizedName().length(); bookletText += entry.getLocalizedName()+"\n\n"; - for(IBookletChapter chapter : entry.getChapters()){ + for(IBookletChapter chapter : entry.getAllChapters()){ bookletWordCount += chapter.getLocalizedName().split(" ").length; bookletCharCount += chapter.getLocalizedName().length(); bookletText += chapter.getLocalizedName()+"\n"; - for(BookletPage page : chapter.getPages()){ - if(page.getText() != null){ - bookletWordCount += page.getText().split(" ").length; - bookletCharCount += page.getText().length(); - bookletText += page.getText()+"\n"; + for(IBookletPage page : chapter.getAllPages()){ + String text = page.getInfoText(); + if(text != null){ + bookletWordCount += text.split(" ").length; + bookletCharCount += text.length(); + bookletText += text+"\n"; } } bookletText += "\n"; diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java index 051418572..bb7ddcab4 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java @@ -102,7 +102,6 @@ public abstract class TileEntityBase extends TileEntity implements ITickable{ register(TileEntityLaserRelayEnergyExtreme.class); register(TileEntityLaserRelayItemWhitelist.class); register(TileEntityItemViewer.class); - register(TileEntityBookletStand.class); register(TileEntityDisplayStand.class); register(TileEntityShockSuppressor.class); register(TileEntityEmpowerer.class); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBookletStand.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBookletStand.java deleted file mode 100644 index 6f80137e9..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBookletStand.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file ("TileEntityBookletStand.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2016 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.tile; - -import de.ellpeck.actuallyadditions.mod.booklet.entry.EntrySet; -import net.minecraft.nbt.NBTTagCompound; - -public class TileEntityBookletStand extends TileEntityBase{ - - public EntrySet assignedEntry = new EntrySet(null); - public String assignedPlayer; - - public TileEntityBookletStand(){ - super("bookletStand"); - } - - @Override - public void writeSyncableNBT(NBTTagCompound compound, NBTType type){ - super.writeSyncableNBT(compound, type); - if(type != NBTType.SAVE_BLOCK){ - NBTTagCompound tag = new NBTTagCompound(); - this.assignedEntry.writeToNBT(tag); - compound.setTag("SavedEntry", tag); - - if(this.assignedPlayer != null){ - compound.setString("Player", this.assignedPlayer); - } - } - } - - @Override - public void readSyncableNBT(NBTTagCompound compound, NBTType type){ - super.readSyncableNBT(compound, type); - if(type != NBTType.SAVE_BLOCK){ - this.assignedEntry.readFromNBT(compound.getCompoundTag("SavedEntry")); - this.assignedPlayer = compound.getString("Player"); - } - } -} \ No newline at end of file diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/util/StringUtil.java b/src/main/java/de/ellpeck/actuallyadditions/mod/util/StringUtil.java index 486fd1e64..c43e15069 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/util/StringUtil.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/util/StringUtil.java @@ -11,6 +11,7 @@ package de.ellpeck.actuallyadditions.mod.util; import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.util.text.translation.I18n; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fml.relauncher.Side; @@ -51,4 +52,26 @@ public final class StringUtil{ public static String getFluidInfo(FluidTank tank){ return ""; } + + + @SideOnly(Side.CLIENT) + public static void renderScaledAsciiString(FontRenderer font, String text, int x, int y, int color, boolean shadow, float scale){ + GlStateManager.pushMatrix(); + GlStateManager.scale(scale, scale, scale); + boolean oldUnicode = font.getUnicodeFlag(); + font.setUnicodeFlag(false); + + font.drawString(text, x/scale, y/scale, color, shadow); + + font.setUnicodeFlag(oldUnicode); + GlStateManager.popMatrix(); + } + + @SideOnly(Side.CLIENT) + public static void renderSplitScaledAsciiString(FontRenderer font, String text, int x, int y, int color, boolean shadow, float scale, int length){ + List lines = font.listFormattedStringToWidth(text, (int)(length*scale)); + for(int i = 0; i < lines.size(); i++){ + renderScaledAsciiString(font, lines.get(i), x, y+(i*font.FONT_HEIGHT), color, shadow, scale); + } + } } diff --git a/src/main/resources/assets/actuallyadditions/textures/gui/booklet/guiBooklet.png b/src/main/resources/assets/actuallyadditions/textures/gui/booklet/guiBooklet.png index 8bbaaf0846cd97d6a91614b4dfa64f61269a1503..b5d463e0def4c9c030c7e1bfcc5c11d7f64ea89c 100644 GIT binary patch literal 25178 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 literal 16670 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

^h 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 TJ+|H`tcP`0_G|MjI7j{$!+1|d diff --git a/src/main/resources/assets/actuallyadditions/textures/gui/booklet/guiBookletAddon.png b/src/main/resources/assets/actuallyadditions/textures/gui/booklet/guiBookletAddon.png deleted file mode 100644 index 5873c000968093ca648d2b261f20d6bc21d6b45e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 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