Creating a Basic Book
Book Structure
The structure is relatively simple:
- Books are made up of lists of Categories.
- Categories are made up of lists of Entries.
- Entries are made up of lists of Pages.
Now, let's create a single Book with a single Category containing a single Entry that contains two pages. The class will be named ExampleBook.java and will be located in com.example.mymod.
Note: Normally you would use unlocalized strings for this, but for the sake of readability, I opted to use localized strings.
package com.example.mymod;
import amerifrance.guideapi.api.GuideAPI;
import amerifrance.guideapi.api.GuideBook;
import amerifrance.guideapi.api.IGuideBook;
import amerifrance.guideapi.api.IPage;
import amerifrance.guideapi.api.impl.Book;
import amerifrance.guideapi.api.impl.abstraction.CategoryAbstract;
import amerifrance.guideapi.api.impl.abstraction.EntryAbstract;
import amerifrance.guideapi.category.CategoryItemStack;
import amerifrance.guideapi.entry.EntryItemStack;
import amerifrance.guideapi.page.PageFurnaceRecipe;
import amerifrance.guideapi.page.PageIRecipe;
import amerifrance.guideapi.page.PageText;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.ShapedOreRecipe;
import javax.annotation.Nonnull;
import java.awt.*;
import java.util.*;
import java.util.List;
@GuideBook
public class ExampleBook implements IGuideBook {
public static Book myGuide;
@Nonnull
@Override
public Book buildBook() {
// Create the map of entries. A LinkedHashMap is used to retain the order of entries.
Map<ResourceLocation, EntryAbstract> entries = new LinkedHashMap<ResourceLocation, EntryAbstract>();
// Creation of our first entry.
List<IPage> pages1 = new ArrayList<IPage>();
pages1.add(new PageText("This is a page in my guide!"));
entries.put(new ResourceLocation("example", "entry_one"), new EntryItemStack(pages1, "Entry One", new ItemStack(Blocks.BEACON)));
// Creation of our second entry.
List<IPage> pages2 = new ArrayList<IPage>();
pages2.add(new PageIRecipe(new ShapedOreRecipe(Items.DIAMOND_SWORD, "D", "D", "S", 'D', Items.DIAMOND, 'S', Items.STICK)));
pages2.add(new PageFurnaceRecipe("oreGold"));
entries.put(new ResourceLocation("example", "entry_two"), new EntryItemStack(pages2, "Entry Two", new ItemStack(Items.DIAMOND_SWORD)));
// Setup the list of categories and add our entries to it.
List<CategoryAbstract> categories = new ArrayList<CategoryAbstract>();
categories.add(new CategoryItemStack(entries, "My Category", new ItemStack(Blocks.COMMAND_BLOCK)));
// Setup the book's base information
myGuide = new Book();
myGuide.setTitle("My Guide");
myGuide.setDisplayName("My Guide");
myGuide.setAuthor("ExampleDude");
myGuide.setColor(Color.CYAN);
myGuide.setCategoryList(categories);
myGuide.setRegistryName(new ResourceLocation("mymod", "first_guide"));
return myGuide;
}
@SideOnly(Side.CLIENT)
@Override
public void handleModel(ItemStack bookStack) {
// Use the default GuideAPI model
GuideAPI.setModel(myGuide);
}
@Override
public void handlePost(ItemStack bookStack) {
// Register a recipe so player's can obtain the book
GameRegistry.addShapelessRecipe(bookStack, Items.BOOK, Items.PAPER);
}
}
Note: Registration is now automatic. The annotation (@GuideBook) is searched for during FMLPreInitializationEvent. All classes annotated with this will be checked if they implement IGuideBook and marked for registration. handleModel(...) is called just after registration during FMLPreInitializationEvent. handlePost(...) is called during FMLPostInitializationEvent.
If your Guide references items from your mod, they must be initialized or it will crash. Make sure to add before:guideapi to your @Mod dependencies field.
You should end up with something similar to this.