From 2e228e6380b0f22ae9a8e5cbf21fab63e3b4383c Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sat, 18 Feb 2017 00:54:58 +0100 Subject: [PATCH] Added trials --- .../api/ActuallyAdditionsAPI.java | 3 +- .../api/booklet/IBookletChapter.java | 4 + .../api/booklet/IBookletEntry.java | 5 + .../api/booklet/IBookletPage.java | 1 + .../api/internal/IMethodHandler.java | 2 + .../mod/achievement/TheAchievements.java | 4 +- .../mod/booklet/InitBooklet.java | 17 ++- .../mod/booklet/button/TrialsButton.java | 52 ++++++++ .../mod/booklet/chapter/BookletChapter.java | 4 + .../booklet/chapter/BookletChapterTrials.java | 45 +++++++ .../mod/booklet/entry/BookletEntry.java | 8 ++ .../mod/booklet/entry/BookletEntryTrials.java | 23 ++++ .../mod/booklet/gui/GuiBooklet.java | 17 ++- .../mod/booklet/gui/GuiEntry.java | 6 + .../mod/booklet/gui/GuiMainPage.java | 24 +++- .../mod/booklet/page/BookletPage.java | 8 +- .../mod/booklet/page/PageCoffeeMachine.java | 4 + .../mod/booklet/page/PageCrusherRecipe.java | 4 + .../mod/booklet/page/PageEmpowerer.java | 4 + .../mod/booklet/page/PageFurnace.java | 4 + .../mod/booklet/page/PageLinkButton.java | 7 +- .../mod/booklet/page/PagePicture.java | 3 + .../mod/booklet/page/PageReconstructor.java | 4 + .../mod/booklet/page/PageTrials.java | 114 ++++++++++++++++++ .../mod/data/PlayerData.java | 26 ++++ .../mod/items/ItemBooklet.java | 1 + .../mod/misc/apiimpl/MethodHandler.java | 6 + .../mod/network/PacketHandler.java | 8 ++ .../mod/network/PacketHandlerHelper.java | 17 +++ .../assets/actuallyadditions/lang/en_US.lang | 29 ++++- .../gui/booklet/gui_booklet_gadgets.png | Bin 7695 -> 8330 bytes 31 files changed, 440 insertions(+), 14 deletions(-) create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/TrialsButton.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterTrials.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryTrials.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTrials.java diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java b/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java index 6bdcf037a..f9cdcf898 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyAdditionsAPI.java @@ -81,7 +81,8 @@ public final class ActuallyAdditionsAPI{ public static IBookletEntry entryMisc; public static IBookletEntry entryUpdatesAndInfos; //This is added to automatically, you don't need to add anything to this entry - public static IBookletEntry allAndSearch; + public static IBookletEntry entryAllAndSearch; + public static IBookletEntry entryTrials; //These are getting initialized in Actually Additions' PreInit phase //DO NOT CHANGE/OVERRIDE THESE!! 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 154ff149c..d20994617 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletChapter.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletChapter.java @@ -11,13 +11,17 @@ package de.ellpeck.actuallyadditions.api.booklet; import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; public interface IBookletChapter{ IBookletPage[] getAllPages(); + @SideOnly(Side.CLIENT) String getLocalizedName(); + @SideOnly(Side.CLIENT) String getLocalizedNameWithFormatting(); IBookletEntry getEntry(); 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 6f8ca1c3a..1656165a4 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletEntry.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletEntry.java @@ -21,8 +21,10 @@ public interface IBookletEntry{ String getIdentifier(); + @SideOnly(Side.CLIENT) String getLocalizedName(); + @SideOnly(Side.CLIENT) String getLocalizedNameWithFormatting(); void addChapter(IBookletChapter chapter); @@ -31,4 +33,7 @@ public interface IBookletEntry{ List getChaptersForDisplay(String searchBarText); int getSortingPriority(); + + @SideOnly(Side.CLIENT) + boolean visibleOnFrontPage(); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java index 3ecd07e29..663647332 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/booklet/IBookletPage.java @@ -29,6 +29,7 @@ public interface IBookletPage{ void setChapter(IBookletChapter chapter); + @SideOnly(Side.CLIENT) String getInfoText(); @SideOnly(Side.CLIENT) 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 1a5dbba27..92c292579 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/internal/IMethodHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/internal/IMethodHandler.java @@ -63,4 +63,6 @@ public interface IMethodHandler{ IBookletPage generateFurnacePage(int id, ItemStack input, ItemStack result, int priority); IBookletChapter generateBookletChapter(String identifier, IBookletEntry entry, ItemStack displayStack, int priority, IBookletPage... pages); + + IBookletChapter createTrial(String identifier, ItemStack displayStack, boolean textOnSecondPage); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/achievement/TheAchievements.java b/src/main/java/de/ellpeck/actuallyadditions/mod/achievement/TheAchievements.java index 86fd7385b..53e2cb8eb 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/achievement/TheAchievements.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/achievement/TheAchievements.java @@ -18,6 +18,7 @@ import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.Util; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.stats.Achievement; import net.minecraft.stats.StatisticsManager; @@ -53,7 +54,8 @@ public enum TheAchievements{ GET_UNPROBED("getUnProbed", -7, 3, new ItemStack(InitItems.itemPlayerProbe), null, Type.MISC, true, 0), GET_CRYSTALS_MILESTONE("getCrystalsMilestone", 6, -3, new ItemStack(InitBlocks.blockCrystal, 1, TheCrystals.DIAMOND.ordinal()), null, Type.PICK_UP, true, 200, new ItemStack(InitItems.itemCrystal, 1, Util.WILDCARD), new ItemStack(InitBlocks.blockCrystal, 1, Util.WILDCARD)), - OPEN_BOOKLET_MILESTONE("openBookletMilestone", 6, -1, new ItemStack(InitItems.itemBooklet), null, Type.MISC, true, 50); + OPEN_BOOKLET_MILESTONE("openBookletMilestone", 6, -1, new ItemStack(InitItems.itemBooklet), null, Type.MISC, true, 50), + COMPLETE_TRIALS("completeTrials", 6, 1, new ItemStack(Items.GOLD_INGOT), null, Type.MISC, true, 0); public final Achievement chieve; public final Type type; 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 56022b561..99d5a5759 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/InitBooklet.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/InitBooklet.java @@ -20,8 +20,10 @@ 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.chapter.BookletChapterTrials; import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntry; import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntryAllItems; +import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntryTrials; import de.ellpeck.actuallyadditions.mod.booklet.page.*; import de.ellpeck.actuallyadditions.mod.crafting.*; import de.ellpeck.actuallyadditions.mod.fluids.InitFluids; @@ -44,16 +46,19 @@ import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; +import net.minecraftforge.common.ForgeModContainer; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.UniversalBucket; import java.util.*; public final class InitBooklet{ - public static BookletChapter[] chaptersIntroduction = new BookletChapter[10]; + public static BookletChapter[] chaptersIntroduction = new BookletChapter[11]; public static void preInit(){ - ActuallyAdditionsAPI.allAndSearch = new BookletEntryAllItems("allAndSearch").setImportant(); + ActuallyAdditionsAPI.entryAllAndSearch = new BookletEntryAllItems("allAndSearch").setImportant(); + ActuallyAdditionsAPI.entryTrials = new BookletEntryTrials("trials"); ActuallyAdditionsAPI.entryGettingStarted = new BookletEntry("gettingStarted").setImportant(); ActuallyAdditionsAPI.entryReconstruction = new BookletEntry("reconstruction"); @@ -275,5 +280,13 @@ public final class InitBooklet{ new BookletChapter("curse", ActuallyAdditionsAPI.entryUpdatesAndInfos, new ItemStack(Items.FLINT_AND_STEEL), new PageLinkButton(1, "http://ellpeck.de/actadd")); new BookletChapter("patreon", ActuallyAdditionsAPI.entryUpdatesAndInfos, new ItemStack(InitItems.itemCrystal, 1, TheCrystals.EMERALD.ordinal()), new PageLinkButton(1, "http://patreon.com/Ellpeck"), new PagePicture(2, "page_patreon", 153)).setImportant(); new BookletChapter("website", ActuallyAdditionsAPI.entryUpdatesAndInfos, new ItemStack(InitItems.itemBooklet), new PageLinkButton(1, "http://ellpeck.de")); + + //Trials + chaptersIntroduction[10] = new BookletChapter("trialsIntro", ActuallyAdditionsAPI.entryTrials, new ItemStack(Items.GOLD_INGOT), new PageTextOnly(1), new PageTextOnly(2)).setSpecial(); + new BookletChapterTrials("leatherProduction", new ItemStack(Items.LEATHER), false); + new BookletChapterTrials("crystalOil", UniversalBucket.getFilledBucket(ForgeModContainer.getInstance().universalBucket, InitFluids.fluidCrystalOil), false); + new BookletChapterTrials("autoDisenchanter", new ItemStack(InitItems.itemDisenchantingLens), false); + new BookletChapterTrials("empoweredOil", UniversalBucket.getFilledBucket(ForgeModContainer.getInstance().universalBucket, InitFluids.fluidEmpoweredOil), false); + new BookletChapterTrials("mobFarm", new ItemStack(Items.ROTTEN_FLESH), false); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/TrialsButton.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/TrialsButton.java new file mode 100644 index 000000000..a45ea05d8 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/button/TrialsButton.java @@ -0,0 +1,52 @@ +/* + * This file ("TrialsButton.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-2017 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.button; + +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 net.minecraft.client.Minecraft; + +public class TrialsButton extends TexturedButton{ + + private final boolean isTrials; + + public TrialsButton(GuiBooklet gui){ + super(GuiBooklet.RES_LOC_GADGETS, -152000, gui.getGuiLeft()+gui.getSizeX(), gui.getGuiTop()+10, 0, 204, 52, 16); + this.isTrials = gui.areTrialsOpened(); + this.enabled = !this.isTrials; + } + + @Override + public void drawButton(Minecraft minecraft, int x, int y){ + super.drawButton(minecraft, x, y); + + if(this.visible){ + if(this.hovered || this.isTrials){ + this.drawCenteredString(minecraft.fontRendererObj, StringUtil.localize("booklet."+ModUtil.MOD_ID+".trialsButton.name"), this.xPosition+(this.width-8)/2, this.yPosition+(this.height-8)/2, 14737632); + } + } + } + + @Override + protected int getHoverState(boolean mouseOver){ + if(mouseOver || this.isTrials){ + return 2; + } + else if(!this.enabled){ + return 0; + } + else{ + return 1; + } + } +} 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 f1ddecf56..178efb3ba 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 @@ -17,6 +17,8 @@ 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.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; public class BookletChapter implements IBookletChapter{ @@ -51,11 +53,13 @@ public class BookletChapter implements IBookletChapter{ } @Override + @SideOnly(Side.CLIENT) public String getLocalizedName(){ return StringUtil.localize("booklet."+ModUtil.MOD_ID+".chapter."+this.getIdentifier()+".name"); } @Override + @SideOnly(Side.CLIENT) public String getLocalizedNameWithFormatting(){ return this.color+this.getLocalizedName(); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterTrials.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterTrials.java new file mode 100644 index 000000000..d950941d8 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/chapter/BookletChapterTrials.java @@ -0,0 +1,45 @@ +/* + * This file ("BookletChapterTrials.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-2017 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.chapter; + +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.mod.booklet.page.PageTrials; +import de.ellpeck.actuallyadditions.mod.data.PlayerData; +import de.ellpeck.actuallyadditions.mod.util.ModUtil; +import de.ellpeck.actuallyadditions.mod.util.StringUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +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 BookletChapterTrials extends BookletChapter{ + + public BookletChapterTrials(String identifier, ItemStack displayStack, boolean secondPageText){ + super(identifier, ActuallyAdditionsAPI.entryTrials, displayStack, new PageTrials(1, false, true), new PageTrials(2, true, secondPageText)); + } + + @Override + @SideOnly(Side.CLIENT) + public String getLocalizedName(){ + return StringUtil.localize("booklet."+ModUtil.MOD_ID+".trials."+this.getIdentifier()+".name"); + } + + @Override + public String getLocalizedNameWithFormatting(){ + EntityPlayer player = Minecraft.getMinecraft().player; + PlayerData.PlayerSave data = PlayerData.getDataFromPlayer(player); + boolean completed = data.completedTrials.contains(this.getIdentifier()); + + return (completed ? TextFormatting.DARK_GREEN : TextFormatting.DARK_RED)+this.getLocalizedName(); + } +} 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 b3e9fae7e..37ae3d9d7 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 @@ -93,11 +93,13 @@ public class BookletEntry implements IBookletEntry{ } @Override + @SideOnly(Side.CLIENT) public String getLocalizedName(){ return StringUtil.localize("booklet."+ModUtil.MOD_ID+".indexEntry."+this.getIdentifier()+".name"); } @Override + @SideOnly(Side.CLIENT) public String getLocalizedNameWithFormatting(){ return this.color+this.getLocalizedName(); } @@ -140,6 +142,12 @@ public class BookletEntry implements IBookletEntry{ return this.priority; } + @Override + @SideOnly(Side.CLIENT) + public boolean visibleOnFrontPage(){ + return true; + } + public BookletEntry setImportant(){ this.color = TextFormatting.DARK_GREEN; return this; diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryTrials.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryTrials.java new file mode 100644 index 000000000..15ddf4cda --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/entry/BookletEntryTrials.java @@ -0,0 +1,23 @@ +/* + * This file ("BookletEntryTrials.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-2017 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.entry; + +public class BookletEntryTrials extends BookletEntry{ + + public BookletEntryTrials(String identifier){ + super(identifier, -Integer.MAX_VALUE); + } + + @Override + public boolean visibleOnFrontPage(){ + return false; + } +} 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 index eec27e08a..bda7702e6 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiBooklet.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiBooklet.java @@ -13,6 +13,7 @@ package de.ellpeck.actuallyadditions.mod.booklet.gui; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; import de.ellpeck.actuallyadditions.api.booklet.internal.GuiBookletBase; import de.ellpeck.actuallyadditions.mod.booklet.button.BookmarkButton; +import de.ellpeck.actuallyadditions.mod.booklet.button.TrialsButton; import de.ellpeck.actuallyadditions.mod.config.values.ConfigIntValues; import de.ellpeck.actuallyadditions.mod.data.PlayerData; import de.ellpeck.actuallyadditions.mod.data.PlayerData.PlayerSave; @@ -55,6 +56,8 @@ public abstract class GuiBooklet extends GuiBookletBase{ private GuiButton buttonRight; private GuiButton buttonBack; + private GuiButton buttonTrials; + private float smallFontSize; private float mediumFontSize; private float largeFontSize; @@ -130,6 +133,9 @@ public abstract class GuiBooklet extends GuiBookletBase{ } } } + + this.buttonTrials = new TrialsButton(this); + this.buttonList.add(this.buttonTrials); } @Override @@ -140,6 +146,7 @@ public abstract class GuiBooklet extends GuiBookletBase{ this.previousScreen = null; PlayerSave data = PlayerData.getDataFromPlayer(this.mc.player); + data.lastOpenBooklet = this; boolean change = false; for(int i = 0; i < this.bookmarkButtons.length; i++){ @@ -148,7 +155,6 @@ public abstract class GuiBooklet extends GuiBookletBase{ change = true; } } - data.lastOpenBooklet = this; if(change){ PacketHandlerHelper.sendPlayerDataToServer(true, 0); @@ -256,6 +262,10 @@ public abstract class GuiBooklet extends GuiBookletBase{ } + public boolean areTrialsOpened(){ + return false; + } + public boolean hasBackButton(){ return false; } @@ -289,7 +299,7 @@ public abstract class GuiBooklet extends GuiBookletBase{ public void onSearchBarChanged(String searchBarText){ GuiBookletBase parent = !(this instanceof GuiEntry) ? this : this.parentPage; - this.mc.displayGuiScreen(new GuiEntry(this.previousScreen, parent, ActuallyAdditionsAPI.allAndSearch, 0, searchBarText, true)); + this.mc.displayGuiScreen(new GuiEntry(this.previousScreen, parent, ActuallyAdditionsAPI.entryAllAndSearch, 0, searchBarText, true)); } @Override @@ -303,6 +313,9 @@ public abstract class GuiBooklet extends GuiBookletBase{ else if(this.hasBackButton() && button == this.buttonBack){ this.onBackButtonPressed(); } + if(button == this.buttonTrials){ + this.mc.displayGuiScreen(new GuiEntry(this.previousScreen, this, ActuallyAdditionsAPI.entryTrials, 0, "", false)); + } else if(this.hasBookmarkButtons() && button instanceof BookmarkButton){ int index = ArrayUtils.indexOf(this.bookmarkButtons, button); if(index >= 0){ 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 index ad94f5bca..4c45557df 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiEntry.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiEntry.java @@ -15,6 +15,7 @@ import de.ellpeck.actuallyadditions.api.booklet.IBookletEntry; import de.ellpeck.actuallyadditions.api.booklet.IBookletPage; import de.ellpeck.actuallyadditions.api.booklet.internal.GuiBookletBase; import de.ellpeck.actuallyadditions.mod.booklet.button.EntryButton; +import de.ellpeck.actuallyadditions.mod.booklet.entry.BookletEntryTrials; import de.ellpeck.actuallyadditions.mod.booklet.misc.BookletUtils; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; @@ -160,4 +161,9 @@ public class GuiEntry extends GuiBooklet{ super.onBackButtonPressed(); } } + + @Override + public boolean areTrialsOpened(){ + return this.entry instanceof BookletEntryTrials; + } } 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 index b7abd22dd..17e625f0b 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiMainPage.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/gui/GuiMainPage.java @@ -204,8 +204,9 @@ public class GuiMainPage extends GuiBooklet{ } for(int i = 0; i < BUTTONS_PER_PAGE; i++){ - if(ActuallyAdditionsAPI.BOOKLET_ENTRIES.size() > i){ - IBookletEntry entry = ActuallyAdditionsAPI.BOOKLET_ENTRIES.get(i); + List displayed = getDisplayedEntries(); + if(displayed.size() > i){ + IBookletEntry entry = displayed.get(i); this.buttonList.add(new EntryButton(this, i, this.guiLeft+156, this.guiTop+11+i*13, 115, 10, "- "+entry.getLocalizedNameWithFormatting(), null)); } else{ @@ -217,8 +218,9 @@ public class GuiMainPage extends GuiBooklet{ @Override protected void actionPerformed(GuiButton button) throws IOException{ if(button instanceof EntryButton){ - if(ActuallyAdditionsAPI.BOOKLET_ENTRIES.size() > button.id){ - IBookletEntry entry = ActuallyAdditionsAPI.BOOKLET_ENTRIES.get(button.id); + List displayed = getDisplayedEntries(); + if(displayed.size() > button.id){ + IBookletEntry entry = displayed.get(button.id); if(entry != null){ this.mc.displayGuiScreen(new GuiEntry(this.previousScreen, this, entry, 0, "", false)); } @@ -247,7 +249,7 @@ public class GuiMainPage extends GuiBooklet{ PlayerSave data = PlayerData.getDataFromPlayer(this.mc.player); data.didBookTutorial = true; - PacketHandlerHelper.sendPlayerDataToServer(true, 1); + PacketHandlerHelper.sendPlayerDataToServer(false, 1); } } else{ @@ -285,4 +287,16 @@ public class GuiMainPage extends GuiBooklet{ public void addOrModifyItemRenderer(ItemStack renderedStack, int x, int y, float scale, boolean shouldTryTransfer){ } + + private static List getDisplayedEntries(){ + List displayed = new ArrayList(); + + for(IBookletEntry entry : ActuallyAdditionsAPI.BOOKLET_ENTRIES){ + if(entry.visibleOnFrontPage()){ + displayed.add(entry); + } + } + + return displayed; + } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPage.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPage.java index c47589ec9..c76d7ecf4 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPage.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/BookletPage.java @@ -66,12 +66,13 @@ public class BookletPage implements IBookletPage{ } @Override + @SideOnly(Side.CLIENT) public String getInfoText(){ if(this.hasNoText){ return null; } - String base = StringUtil.localize("booklet."+ModUtil.MOD_ID+".chapter."+this.chapter.getIdentifier()+".text."+this.localizationKey); + String base = StringUtil.localize(this.getLocalizationKey()); base = base.replaceAll("", TextFormatting.DARK_GREEN+""); base = base.replaceAll("", TextFormatting.BLUE+""); base = base.replaceAll("", TextFormatting.BLACK+""); @@ -85,6 +86,11 @@ public class BookletPage implements IBookletPage{ return base; } + @SideOnly(Side.CLIENT) + protected String getLocalizationKey(){ + return "booklet."+ModUtil.MOD_ID+".chapter."+this.chapter.getIdentifier()+".text."+this.localizationKey; + } + @Override @SideOnly(Side.CLIENT) public void mouseClicked(GuiBookletBase gui, int mouseX, int mouseY, int mouseButton){ diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeMachine.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeMachine.java index dd0d5d44c..242de69c0 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeMachine.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCoffeeMachine.java @@ -18,6 +18,8 @@ import de.ellpeck.actuallyadditions.mod.items.InitItems; import de.ellpeck.actuallyadditions.mod.items.metalists.TheMiscItems; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; @@ -35,6 +37,7 @@ public class PageCoffeeMachine extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); @@ -48,6 +51,7 @@ public class PageCoffeeMachine extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void initGui(GuiBookletBase gui, int startX, int startY){ super.initGui(gui, startX, startY); 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 index 1c1eb2569..218b98775 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrusherRecipe.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageCrusherRecipe.java @@ -18,6 +18,8 @@ import de.ellpeck.actuallyadditions.mod.util.StackUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; @@ -31,6 +33,7 @@ public class PageCrusherRecipe extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); @@ -43,6 +46,7 @@ public class PageCrusherRecipe extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void initGui(GuiBookletBase gui, int startX, int startY){ super.initGui(gui, startX, startY); 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 index a6f20d00a..1c9e9b374 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageEmpowerer.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageEmpowerer.java @@ -17,6 +17,8 @@ import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; @@ -30,6 +32,7 @@ public class PageEmpowerer extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); @@ -42,6 +45,7 @@ public class PageEmpowerer extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void initGui(GuiBookletBase gui, int startX, int startY){ super.initGui(gui, startX, startY); 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 index 6ffa1405c..b52c19de2 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageFurnace.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageFurnace.java @@ -18,6 +18,8 @@ import de.ellpeck.actuallyadditions.mod.util.StringUtil; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; import java.util.Map; @@ -50,6 +52,7 @@ public class PageFurnace extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); @@ -62,6 +65,7 @@ public class PageFurnace extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void initGui(GuiBookletBase gui, int startX, int startY){ super.initGui(gui, startX, startY); 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 index b3020ac3b..9c1acf431 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageLinkButton.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageLinkButton.java @@ -14,13 +14,15 @@ import de.ellpeck.actuallyadditions.api.booklet.internal.GuiBookletBase; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import de.ellpeck.actuallyadditions.mod.util.StringUtil; import net.minecraft.client.gui.GuiButton; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.awt.*; import java.net.URI; public class PageLinkButton extends BookletPage{ - private static int nextButtonId = 23782; + public static int nextButtonId = 23782; private final int buttonId; private final String link; @@ -34,6 +36,7 @@ public class PageLinkButton extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void initGui(GuiBookletBase gui, int startX, int startY){ super.initGui(gui, startX, startY); @@ -41,12 +44,14 @@ public class PageLinkButton extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); PageTextOnly.renderTextToPage(gui, this, startX+6, startY+5); } @Override + @SideOnly(Side.CLIENT) public void actionPerformed(GuiBookletBase gui, GuiButton button){ if(button.id == this.buttonId){ if(Desktop.isDesktopSupported()){ 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 index a5aaf6cb6..6722d505c 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PagePicture.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PagePicture.java @@ -15,6 +15,8 @@ import de.ellpeck.actuallyadditions.mod.util.AssetUtil; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; public class PagePicture extends BookletPage{ @@ -38,6 +40,7 @@ public class PagePicture extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); 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 index e6e0e056e..cb5a87764 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageReconstructor.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageReconstructor.java @@ -18,6 +18,8 @@ import de.ellpeck.actuallyadditions.mod.util.StringUtil; import de.ellpeck.actuallyadditions.mod.util.Util; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; @@ -32,6 +34,7 @@ public class PageReconstructor extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); @@ -44,6 +47,7 @@ public class PageReconstructor extends BookletPage{ } @Override + @SideOnly(Side.CLIENT) public void initGui(GuiBookletBase gui, int startX, int startY){ super.initGui(gui, startX, startY); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTrials.java b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTrials.java new file mode 100644 index 000000000..0a657422e --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/booklet/page/PageTrials.java @@ -0,0 +1,114 @@ +/* + * This file ("PageTrials.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-2017 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.booklet.page; + +import de.ellpeck.actuallyadditions.api.booklet.internal.GuiBookletBase; +import de.ellpeck.actuallyadditions.mod.data.PlayerData; +import de.ellpeck.actuallyadditions.mod.data.PlayerData.PlayerSave; +import de.ellpeck.actuallyadditions.mod.network.PacketHandlerHelper; +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; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class PageTrials extends BookletPage{ + + @SideOnly(Side.CLIENT) + private GuiButton button; + + private final int buttonId; + + public PageTrials(int localizationKey, boolean button, boolean text){ + super(localizationKey); + + if(!text){ + this.setNoText(); + } + + if(button){ + this.buttonId = PageLinkButton.nextButtonId; + PageLinkButton.nextButtonId++; + } + else{ + this.buttonId = -1; + } + } + + @Override + @SideOnly(Side.CLIENT) + public void initGui(GuiBookletBase gui, int startX, int startY){ + super.initGui(gui, startX, startY); + + if(this.buttonId >= 0){ + this.button = new GuiButton(this.buttonId, startX+125/2-50, startY+120, 100, 20, ""); + gui.getButtonList().add(this.button); + this.updateButton(); + } + } + + @Override + @SideOnly(Side.CLIENT) + public void drawScreenPre(GuiBookletBase gui, int startX, int startY, int mouseX, int mouseY, float partialTicks){ + super.drawScreenPre(gui, startX, startY, mouseX, mouseY, partialTicks); + PageTextOnly.renderTextToPage(gui, this, startX+6, startY+5); + } + + @Override + @SideOnly(Side.CLIENT) + protected String getLocalizationKey(){ + return "booklet."+ModUtil.MOD_ID+".trials."+this.chapter.getIdentifier()+".text."+this.localizationKey; + } + + @Override + @SideOnly(Side.CLIENT) + public void actionPerformed(GuiBookletBase gui, GuiButton button){ + if(this.buttonId >= 0 && button.id == this.buttonId){ + EntityPlayer player = Minecraft.getMinecraft().player; + PlayerSave data = PlayerData.getDataFromPlayer(player); + String id = this.chapter.getIdentifier(); + + boolean completed = data.completedTrials.contains(id); + if(completed){ + data.completedTrials.remove(id); + } + else{ + data.completedTrials.add(id); + } + this.updateButton(); + + PacketHandlerHelper.sendPlayerDataToServer(false, 2); + } + else{ + super.actionPerformed(gui, button); + } + } + + @SideOnly(Side.CLIENT) + private void updateButton(){ + if(this.buttonId >= 0 && this.button != null){ + EntityPlayer player = Minecraft.getMinecraft().player; + PlayerSave data = PlayerData.getDataFromPlayer(player); + + boolean completed = data.completedTrials.contains(this.chapter.getIdentifier()); + if(completed){ + this.button.displayString = TextFormatting.DARK_GREEN+StringUtil.localize("booklet."+ModUtil.MOD_ID+".trialFinishButton.completed.name"); + } + else{ + this.button.displayString = TextFormatting.DARK_RED+StringUtil.localize("booklet."+ModUtil.MOD_ID+".trialFinishButton.uncompleted.name"); + } + + } + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/data/PlayerData.java b/src/main/java/de/ellpeck/actuallyadditions/mod/data/PlayerData.java index 1a67f3fc0..b124ed2f9 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/data/PlayerData.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/data/PlayerData.java @@ -20,6 +20,8 @@ import net.minecraft.nbt.NBTTagString; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -55,6 +57,7 @@ public final class PlayerData{ public int batWingsFlyTime; public IBookletPage[] bookmarks = new IBookletPage[12]; + public List completedTrials = new ArrayList(); @SideOnly(Side.CLIENT) public GuiBooklet lastOpenBooklet; @@ -73,6 +76,9 @@ public final class PlayerData{ NBTTagList bookmarks = compound.getTagList("Bookmarks", 8); this.loadBookmarks(bookmarks); + NBTTagList trials = compound.getTagList("Trials", 8); + this.loadTrials(trials); + if(!savingToFile){ this.shouldDisableBatWings = compound.getBoolean("ShouldDisableWings"); } @@ -86,6 +92,7 @@ public final class PlayerData{ compound.setInteger("BatWingsFlyTime", this.batWingsFlyTime); compound.setTag("Bookmarks", this.saveBookmarks()); + compound.setTag("Trials", this.saveTrials()); if(!savingToFile){ compound.setBoolean("ShouldDisableWings", this.shouldDisableBatWings); @@ -112,6 +119,25 @@ public final class PlayerData{ } } } + + public NBTTagList saveTrials(){ + NBTTagList trials = new NBTTagList(); + for(String trial : this.completedTrials){ + trials.appendTag(new NBTTagString(trial)); + } + return trials; + } + + public void loadTrials(NBTTagList trials){ + this.completedTrials.clear(); + + for(int i = 0; i < trials.tagCount(); i++){ + String strg = trials.getStringTagAt(i); + if(strg != null && !strg.isEmpty()){ + this.completedTrials.add(strg); + } + } + } } 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 d4738a10f..2fad184fd 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemBooklet.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemBooklet.java @@ -100,6 +100,7 @@ public class ItemBooklet extends ItemBase implements IHudDisplay{ } @Override + @SideOnly(Side.CLIENT) public void displayHud(Minecraft minecraft, EntityPlayer player, ItemStack stack, RayTraceResult posHit, ScaledResolution resolution){ if(posHit != null && posHit.getBlockPos() != null){ IBlockState state = minecraft.world.getBlockState(posHit.getBlockPos()); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/misc/apiimpl/MethodHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/misc/apiimpl/MethodHandler.java index 53dfac88a..64d6879c3 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/misc/apiimpl/MethodHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/misc/apiimpl/MethodHandler.java @@ -19,6 +19,7 @@ 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.chapter.BookletChapterTrials; import de.ellpeck.actuallyadditions.mod.booklet.page.PageCrafting; import de.ellpeck.actuallyadditions.mod.booklet.page.PageFurnace; import de.ellpeck.actuallyadditions.mod.booklet.page.PagePicture; @@ -308,4 +309,9 @@ public class MethodHandler implements IMethodHandler{ public IBookletChapter generateBookletChapter(String identifier, IBookletEntry entry, ItemStack displayStack, int priority, IBookletPage... pages){ return new BookletChapter(identifier, entry, displayStack, priority, pages); } + + @Override + public IBookletChapter createTrial(String identifier, ItemStack displayStack, boolean textOnSecondPage){ + return new BookletChapterTrials(identifier, displayStack, textOnSecondPage); + } } 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 360e24551..50a3ac449 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java @@ -11,6 +11,7 @@ package de.ellpeck.actuallyadditions.mod.network; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import de.ellpeck.actuallyadditions.mod.achievement.TheAchievements; import de.ellpeck.actuallyadditions.mod.data.PlayerData; import de.ellpeck.actuallyadditions.mod.data.WorldData; import de.ellpeck.actuallyadditions.mod.network.gui.IButtonReactor; @@ -170,6 +171,13 @@ public final class PacketHandler{ else if(type == 1){ data.didBookTutorial = compound.getBoolean("DidBookTutorial"); } + else if(type == 2){ + data.loadTrials(compound.getTagList("Trials", 8)); + + if(compound.getBoolean("Achievement")){ + TheAchievements.COMPLETE_TRIALS.get(player); + } + } WorldData.get(world).markDirty(); if(compound.getBoolean("Log")){ diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandlerHelper.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandlerHelper.java index 58ce667e1..a4deed7bd 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandlerHelper.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandlerHelper.java @@ -10,6 +10,9 @@ package de.ellpeck.actuallyadditions.mod.network; +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; +import de.ellpeck.actuallyadditions.mod.booklet.chapter.BookletChapterTrials; import de.ellpeck.actuallyadditions.mod.data.PlayerData; import de.ellpeck.actuallyadditions.mod.data.PlayerData.PlayerSave; import net.minecraft.client.Minecraft; @@ -68,6 +71,20 @@ public final class PacketHandlerHelper{ else if(type == 1){ compound.setBoolean("DidBookTutorial", data.didBookTutorial); } + else if(type == 2){ + compound.setTag("Trials", data.saveTrials()); + + int total = 0; + for(IBookletChapter chapter : ActuallyAdditionsAPI.entryTrials.getAllChapters()){ + if(chapter instanceof BookletChapterTrials){ + total++; + } + } + + if(data.completedTrials.size() >= total){ + compound.setBoolean("Achievement", true); + } + } PacketHandler.theNetwork.sendToServer(new PacketClientToServer(compound, PacketHandler.PLAYER_DATA_TO_SERVER)); } diff --git a/src/main/resources/assets/actuallyadditions/lang/en_US.lang b/src/main/resources/assets/actuallyadditions/lang/en_US.lang index ee701e512..286a14b95 100644 --- a/src/main/resources/assets/actuallyadditions/lang/en_US.lang +++ b/src/main/resources/assets/actuallyadditions/lang/en_US.lang @@ -811,6 +811,9 @@ achievement.actuallyadditions.openBookletMilestone.desc=Open the Manual 50 times achievement.actuallyadditions.getUnProbed=Sneaky! achievement.actuallyadditions.getUnProbed.desc=Be probed by someone but sneak and notice it +achievement.actuallyadditions.completeTrials=A Botanist's Dream +achievement.actuallyadditions.completeTrials.desc=Complete all Trials in the Manual + #Booklet Recipe Names booklet.actuallyadditions.shapelessRecipe=Shapeless Recipe booklet.actuallyadditions.shapedRecipe=Shaped Recipe @@ -834,6 +837,7 @@ booklet.actuallyadditions.indexEntry.itemsRF.name=Items that use CF booklet.actuallyadditions.indexEntry.reconstruction.name=Reconstruction booklet.actuallyadditions.indexEntry.laserRelays.name=Laser Transport booklet.actuallyadditions.indexEntry.updatesAndInfos.name=Updates and Infos +booklet.actuallyadditions.indexEntry.trials.name=Trials #Booklet Font Size booklet.actuallyadditions.fontSize.small=0.5 @@ -851,6 +855,9 @@ booklet.actuallyadditions.configButton.name=Open Config GUI booklet.actuallyadditions.configButton.desc=Press this to configure %s in-game. \nSome changes will require a game restart! booklet.actuallyadditions.achievementButton.name=Open Achievements booklet.actuallyadditions.achievementButton.desc=Press this to open the %s Achievements. +booklet.actuallyadditions.trialFinishButton.completed.name=Completed +booklet.actuallyadditions.trialFinishButton.uncompleted.name=Not Completed +booklet.actuallyadditions.trialsButton.name=Trials #Booklet Info booklet.actuallyadditions.recipeDisabled=The crafting recipe for this item is disabled in the Config File! If you're on a server, ask the server author to enable it in the config. If you're on a client, press the 'Open Config'-Button on the top right and enable the recipe! @@ -858,6 +865,22 @@ booklet.actuallyadditions.unavailable=Parts of this feature are currently disabl booklet.actuallyadditions.clickToSeeRecipe=Click to see more Information booklet.actuallyadditions.amountOfWordsAndChars=Total: %s words, %s characters +#Booklet Trials +booklet.actuallyadditions.trials.leatherProduction.name=Leather Production +booklet.actuallyadditions.trials.leatherProduction.text.1=Automating the Atomic Reconstructor can be a nice thing, especially when trying to create Leather from Rotten Flesh, allowing you to finally get some use out of those nasty unwanted resources. + +booklet.actuallyadditions.trials.crystalOil.name=Automate Crystallized Oil +booklet.actuallyadditions.trials.crystalOil.text.1=The first and second tier of Oil are very easy to create, however, if you want to create a lot more power, it gets more complicated the higher tier you go with. Creating Crystallized Oil requires an automated setup that converts Oil in-world, requiring a more advanced setup. + +booklet.actuallyadditions.trials.autoDisenchanter.name=Auto-Disenchanter +booklet.actuallyadditions.trials.autoDisenchanter.text.1=Using the Lens of Disenchanting makes it really easy to get enchantments off of things that you don't want them on anymore, like loot from the Fishing Net or dungeons and unlucky enchantments on your favorite tools. Automating this process would make things a lot easier. + +booklet.actuallyadditions.trials.empoweredOil.name=Automate Empowered Oil +booklet.actuallyadditions.trials.empoweredOil.text.1=The demand for power has been rising and rising, yet building more farms just doesn't cut it? You should try to upgrade your Oil production by creating Empowered Oil. However, this requires a pretty advanced in-world setup to get working, so it might be tricky. + +booklet.actuallyadditions.trials.mobFarm.name=Monster Grinder +booklet.actuallyadditions.trials.mobFarm.text.1=Using the Spawner Changer or just a big empty space and some water can be a great way to get a bunch of mobs to spawn. Using the Lens of Death or the Lens of the Killer allows you to efficiently kill mobs and even get special drops, allowing you to create a pretty effective automatic mob farm. + #Booklet Chapters booklet.actuallyadditions.chapter.intro.name=A story about ActAdd booklet.actuallyadditions.chapter.intro.text.1=For too long have the people of Minecraftia toiled under a relentless whip. A whip more hurtful and more injurious than that of any slave-master: inconvenience. Aye, the thousand million inconveniences that make up the grind, that force players to waste hours- nay, days!- chopping wood and farming wheat and other such mundane tasks, just to momentarily escape the remorseless tedium and experience the true joys of Minecraftia, building, caving and adventuring into the beautiful uncharted abundance @@ -1216,4 +1239,8 @@ booklet.actuallyadditions.chapter.goggles.name=Engineer's Goggles booklet.actuallyadditions.chapter.goggles.text.1=The Engineer's Goggles are a very useful item that can be equipped on the player's head. They allow you to see certain information that you wouldn't normally see, like the upgrades on Laser Relays and invisible beams. The Engineer's Infrared Goggles are an upgraded version that additionally allows you to easily see any entity in a small area around you, even when there are blocks in the way, by making them appear glowing. booklet.actuallyadditions.chapter.crystalClusters.name=Crystal Clusters -booklet.actuallyadditions.chapter.crystalClusters.text.1=Crystal Clusters are blocks that generate naturally inside of Lush Caves. When broken, they drop one or more Crystal Shards that can be crafted together to create Crystals. Crystal Clusters emit a bit of light, making them perfect for decoration. To harvest them in their block form, Silk Touch can be used. \ No newline at end of file +booklet.actuallyadditions.chapter.crystalClusters.text.1=Crystal Clusters are blocks that generate naturally inside of Lush Caves. When broken, they drop one or more Crystal Shards that can be crafted together to create Crystals. Crystal Clusters emit a bit of light, making them perfect for decoration. To harvest them in their block form, Silk Touch can be used. + +booklet.actuallyadditions.chapter.trialsIntro.name=Intro to Trials +booklet.actuallyadditions.chapter.trialsIntro.text.1=Trials are a set of fun and interesting challenges that you can use to get inspiration on what to build next. Once you complete a Trial, you can press the button in the bottom right to mark the trial as completed, turning its name in the list green. Since there is no way to check if a trial is actually completed, Trials are meant as personal goals. To visit the Trials page, you can click the bookmark in the top right corner of the manual GUI. +booklet.actuallyadditions.chapter.trialsIntro.text.2=Note that Trials are designed in a way that they should be completed with the concepts of Minecraft and Actually Additions alone. \ No newline at end of file diff --git a/src/main/resources/assets/actuallyadditions/textures/gui/booklet/gui_booklet_gadgets.png b/src/main/resources/assets/actuallyadditions/textures/gui/booklet/gui_booklet_gadgets.png index bd63be8a61063c5c88dc6fd6ae04c4355df5b2d1..402a7ca3d064dfbf631a56377cdda4f810564f96 100644 GIT binary patch literal 8330 zcmbt)c|6qJ+y5D(F=7}g%UEWNLdc#i&5S{~WhtfHvhUflC1n{Jj6|X=kuBOR5jT;n zWlPd(&AzW=U$Q(O-QB|paMl@^;*S#BYVzZYY4XKOYTm0quM(vz=X_t7-ELN@T8PdT@Bi7i*1GueZEJi3 zLo(a+gM=gBUFfTpCxnIIsjz^RTuXt$NYS(_YCG%0QHF$#>@Ja!is^#)tU%i25Ze5G ze7L{HU7Lz!%+^%I_ak=Ziv`A|?0kSxE#{b6shyd1V~jvlijs%LrRt#VA(in|4LDB3 z{5q=d_2poE2!&wKqU0#^?mNqV7=?V9~_EFoNmxokwNAc`@tCjs_hU#hw?mPxLc+CMUxxrY#CY*QR+VuDQWcrI& zLBWWaGZBZtX`A|RRMhxGJvdG=P>#Zy`$IX8zvi+TmxOd-_w{gAQXfMNz`5ozk_U-P z%U_!1KdQy6EjA^_>nZ+7N(SAvz>0_4;+hbOlGF~){%H{)));rfy;@jh`?h?%N6=Er>XYzP#dR!Flk4JBh%Vx@G{H@xf{H;=} zCcuUzr1FxS82p0A=0r@1?6#XL`z{Ri^Wboxs~{y%!-{ z2YY#ITaIYT%ysfnd)}}1)Ig0;MH4}D6U`(KnvdicP2o^8xP^vE4^S4r_ddN8y7_(K6StN zyrtDLHYEuoDE4a9-FocKl}^UbqJ&nVfT4&XZQf0bE4BOfEbS=V$c96GV$mPk68)yy zd&UyF*4Eh=0>uNSBM6y2eMDG~6*|aWk7P=$Xg~lGS-pS648&78sJ=%LWA?h4 zhPqAa1r9>%!h0D#1o$+pWVzPseMcjOa%Ae~+-vEg!fw2_GM0u8y;KyW{nDl$)qE@Z z^;!2zHpUcbv$@g}aih~^_J}Jp-N!`Uces5RZ<$6QaQ*vgL^nrRNEg3HO@tr`j6;pj zVc|7*7?fC0R;pxKGZG!W69Q-AuOJ*OMs5#AU=@pQ1C_cB64j&nn*PhJsaZXIe}Hkz z+{mjBHxgFm;S^ccVb+0>uOzAR%g=Tz?x9XF@dO&N!If8^yD%Xrqr?O{u$)r)Ia6G0 ztJbx^8Kfe}6Np%GIVLqD_(vb~NQ=gv`$v>*wPPSDoxY76onxGHwlWm0;C7mzhkvJsM( zf=lFKGsF3zB}+dbi}4T&O&79544fwMl5V{hMgW-EO!;>CyC3PB--nL*RSlGyq`2Kk zv#7NC09T;I@eC);N^aVK%WB2?r^%mK64ter@c}Tmw_uT)#%RdITtsIr3^y;8$=A)@RKr^WKamqt_SR`to z%O{y#R-;oXaM9Eeq1<3>sTsVi;^#QP3RIiYx7hDyG#KeCDaw+MQj%*2Z1LUuNvyyy;8(U-=zP>1Z%ByauUsN|eSQ8W znYs6B2TQ@p)`6F(VAV2&)ylJ5f*SJD2r#Ijh6`t=#XjL6qT%ax+*JeXTjRueM!{R= zF*$5s-2i&ys|4kV<)7DC&{8YAlj*^!l{-m(qSGA~54W}!*F@P*E*n*BuRxikmB9lp zWwF+%KxvxrB#+es+HV_DqfDhkkvgU5vOI=XdOMYr$ns;dTc!eg(|tvooAW z(O$KPG8Z4BAT8f+voxlsy7pBH`S&yuyznhM zZs)|@tNQ%?kB`HUf}yFWwr~nS=-_qQH!dg$or~sx)0I7cUX%+tx4fgFDU6^G^|P_! z6hiVl+;y+c_syOLS^b69=8L7p#D~mSwUw{N&05^%_fq}30{=0dV;5V;#QzuDf-NjykwX*Y#);Eg%-@!I@`xzyU$Qj+lyM zgh>x2dM(2OSd7we)uzOlDhxn#0(_AF)J<_B9Qn=_R;#ftaiPFxVpB$QLb_@_E7G13 z(pTfHz}aQpx>i8X#J*>wstrD34+?841EUM&A1d&ht^hEwN0VX~3*G*|aE&~+6&yI* z|GAaLozI3hB+W2Cqzv?d-l{`3VBP3r$c?I50_(vC6t$JV=$`~@z-sX3J`AaT`3GR+ z2sl5;lKJ$wKLXeIls(KN(gHb67H(g9c6{q2NM%0A3#gJ-$8pe>?#wd{JgV;e()?9;tq~XMO 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 HR-yj|1HQkN literal 7695 zcmds6XIN8Pmp&mF10<4w^cKJyRD{qJ3ng?>%JteP(yJm(dJmWjL8@W_>F7n2E)qam z=peoKE`mbnod9#t&zW!LnP2mBe&jj(?6cR}Yp=ETyGla;)X_jPax($|fYiLI`WFB| zz##;H!@$SAM;X@OgWg6-TL}R2qnK!B$G~?6r>pud0B|Dx=m!ZIdG82L9(UE$Ry#fp z=SN?Xq<#`z2B)}O)%09%I$FDWm_4!roXqY!xQaVixng9*CB!AAROsy%0D#X+Q&s7f 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�IYVivC}G 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