Skip to content

Commit

Permalink
feat: Leaflets (#216)
Browse files Browse the repository at this point in the history
* feat: add leaflet mode to books

* feat: add default item icon/model for leaflet

* feat: allow linking to specific pages within leaflets

* fix: add texture for leaflet to forge and neo resource folders

datagen for those two loaders seems not to handle common content

* fix: nullable network writing

* feat: add leaflet datagen helpers and demo leaflet

* fix: leaflet closing

* feat: add demo leaflet to datagen for all platforms

* fix: more issues with leaflet closing

* fix: demo leaflet empty spaces

* chore: demo leaflet margins

* chore: run datagen

* chore: re-establish reuse compliance
  • Loading branch information
klikli-dev authored Jun 15, 2024
1 parent 1dfe022 commit 3e18a8c
Show file tree
Hide file tree
Showing 67 changed files with 845 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2024 klikli-dev
//
// SPDX-License-Identifier: MIT

package com.klikli_dev.modonomicon.api.datagen;

import com.klikli_dev.modonomicon.api.datagen.book.BookModel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ public BookCategoryModel generate() {
var category = BookCategoryModel.create(
this.modLoc(this.context().categoryId()),
this.context().categoryName()
)
.withIcon(this.categoryIcon());
);

this.add(this.context().categoryName(), this.categoryName());
var categoryDescription = this.categoryDescription();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: 2024 klikli-dev
//
// SPDX-License-Identifier: MIT

package com.klikli_dev.modonomicon.api.datagen;

import com.klikli_dev.modonomicon.api.datagen.book.BookIconModel;
import net.minecraft.world.item.Items;

/**
* This is a one-size-fits all category provider for leaflets.
* There is no need for leaflets to actually implement category providers, they all use this "dummy one"
*/
class LeafletCategoryProvider extends CategoryProvider{
public static final String ID = "leaflet";

public LeafletCategoryProvider(ModonomiconProviderBase parent) {
super(parent);
}

@Override
protected String[] generateEntryMap() {
return new String[0];
}

@Override
protected void generateEntries() {
//entries are generated in the leaflet subprovider instead.
}

@Override
protected String categoryName() {
return "Leaflet";
}

@Override
protected BookIconModel categoryIcon() {
return BookIconModel.create(Items.PAPER);
}

@Override
protected String categoryId() {
return ID;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: 2024 klikli-dev
//
// SPDX-License-Identifier: MIT

package com.klikli_dev.modonomicon.api.datagen;

import com.klikli_dev.modonomicon.api.datagen.book.BookIconModel;
import com.mojang.datafixers.util.Pair;
import net.minecraft.world.item.Items;

public abstract class LeafletEntryProvider extends EntryProvider {
public static final String ID = "leaflet";

public LeafletEntryProvider(CategoryProvider parent) {
super(parent);
}

@Override
protected String entryName() {
//we assume people don't mess with leaflet provider structure
//If you do and you end up here with an error, just override this method and return an entry name safely :)
var book = (LeafletSubProvider) this.parent.parent;
return book.bookName();
}

@Override
protected String entryDescription() {
return ""; //Irrelevant, because it will never be rendered
}

@Override
protected Pair<Integer, Integer> entryBackground() {
return EntryBackground.DEFAULT;
}

@Override
protected BookIconModel entryIcon() {
return BookIconModel.create(Items.PAPER);
}

@Override
protected String entryId() {
return ID;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2022 klikli-dev
*
* SPDX-License-Identifier: MIT
*/


package com.klikli_dev.modonomicon.api.datagen;

import com.klikli_dev.modonomicon.api.datagen.book.BookModel;
import com.klikli_dev.modonomicon.registry.ItemRegistry;

import java.util.Map;

/**
* An opinionated book leaflet sub provider with helper methods to generate a leaflet more easily.
*/
public abstract class LeafletSubProvider extends SingleBookSubProvider {

public LeafletSubProvider(String bookId, String modId, ModonomiconLanguageProvider defaultLang, ModonomiconLanguageProvider... translations) {
super(bookId, modId, defaultLang, translations);
}

public LeafletSubProvider(String bookId, String modId, ModonomiconLanguageProvider defaultLang, Map<String, ModonomiconLanguageProvider> translations) {
super(bookId, modId, defaultLang, translations);
}

@Override
protected void generateCategories() {
var leafletCategoryProvider = new LeafletCategoryProvider(this);
var leafletCategory = this.add(leafletCategoryProvider.generate());
var entryProvider = this.createEntryProvider(leafletCategoryProvider);
leafletCategory.withEntry(entryProvider.generate());
}

@Override
protected final BookModel additionalSetup(BookModel book) {
return this.additionalLeafletSetup(
book.withLeafletEntry(this.modLoc(LeafletCategoryProvider.ID, LeafletEntryProvider.ID))
.withModel(ItemRegistry.LEAFLET.getId())
);
}

/**
* Implement this and modify the book as needed for additional config.
* Context already is set to this book.
*/
protected BookModel additionalLeafletSetup(BookModel book) {
return book;
}

protected abstract LeafletEntryProvider createEntryProvider(CategoryProvider parent);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import java.util.function.BiConsumer;

/**
* An opinionated book provider with helper methods to generate a single book more easily.
* An opinionated book sub provider with helper methods to generate a single book more easily.
*/
public abstract class SingleBookSubProvider extends ModonomiconProviderBase implements BookSubProvider {
protected BookModel book;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,22 @@

public class BookModel {

/**
* The book ID, e.g. "modonomicon:demo". The ID must be unique (usually that is guaranteed by the mod ID).
*/
protected ResourceLocation id;
/**
* The name of the book, should be a translation key/description id
*/
protected String name;
/**
* The description to (optionally) display on the first page of the category.
*/
protected BookTextHolderModel description = new BookTextHolderModel("");
/**
* The tooltip to optionally display on the book item on hover.
*/
protected String tooltip = "";
protected ResourceLocation creativeTab = ResourceLocation.parse("modonomicon:modonomicon");

protected ResourceLocation model = ResourceLocation.parse(Book.DEFAULT_MODEL);
protected ResourceLocation bookOverviewTexture = ResourceLocation.parse(Data.Book.DEFAULT_OVERVIEW_TEXTURE);
protected ResourceLocation font = ResourceLocation.parse(Book.DEFAULT_FONT);

/**
* The display mode - node based (thaumonomicon style) or index based (lexica botania / patchouli style)
Expand All @@ -42,13 +46,52 @@ public class BookModel {
*/
protected BookDisplayMode displayMode = BookDisplayMode.NODE;

/**
* The creative tab to add the book to.
*/
protected ResourceLocation creativeTab = ResourceLocation.parse("modonomicon:modonomicon");

/**
* If true, automatically generates an item for this book and registers it with the creative tab.
*/
protected boolean generateBookItem = true;

/**
* The item model to use for the book. Only used if generateBookItem = true.
*/
protected ResourceLocation model = ResourceLocation.parse(Book.DEFAULT_MODEL);

/**
* If set, uses this item for the book. That means you need to implement all functionality to open the book yourself.
*/
@Nullable
protected ResourceLocation customBookItem = null;

/**
* This texture contains buttons for the "node view" of the book. E.g. search button, category buttons, "read all" button.
*/
protected ResourceLocation bookOverviewTexture = ResourceLocation.parse(Data.Book.DEFAULT_OVERVIEW_TEXTURE);

/**
* The font to use for the book text.
*/
protected ResourceLocation font = ResourceLocation.parse(Book.DEFAULT_FONT);

protected ResourceLocation frameTexture = ResourceLocation.parse(Book.DEFAULT_FRAME_TEXTURE);
protected BookFrameOverlay topFrameOverlay = Data.Book.DEFAULT_TOP_FRAME_OVERLAY;
protected BookFrameOverlay bottomFrameOverlay = Data.Book.DEFAULT_BOTTOM_FRAME_OVERLAY;
protected BookFrameOverlay leftFrameOverlay = Data.Book.DEFAULT_LEFT_FRAME_OVERLAY;
protected BookFrameOverlay rightFrameOverlay = Data.Book.DEFAULT_RIGHT_FRAME_OVERLAY;

/**
* Contains textures for the entry view, as well as index views (book or category in index mode, as well as search screen).
* This includes the book "page" background and various navigation buttons.
*/
protected ResourceLocation bookContentTexture = ResourceLocation.parse(Data.Book.DEFAULT_CONTENT_TEXTURE);

/**
* Contains textures for the crafting pages, such as crafting grids and result arrows.
*/
protected ResourceLocation craftingTexture = ResourceLocation.parse(Book.DEFAULT_CRAFTING_TEXTURE);
protected int defaultTitleColor = 0x00000;
protected float categoryButtonIconScale = 1.0f;
Expand All @@ -57,10 +100,7 @@ public class BookModel {
protected List<BookCommandModel> commands = new ArrayList<>();

protected boolean autoAddReadConditions = false;
protected boolean generateBookItem = true;

@Nullable
protected ResourceLocation customBookItem = null;

/**
* When rendering book text holders, add this offset to the x position (basically, create a left margin).
Expand All @@ -79,13 +119,21 @@ public class BookModel {
*/
protected int bookTextOffsetWidth = 0;


protected int categoryButtonXOffset = 0;
protected int categoryButtonYOffset = 0;
protected int searchButtonXOffset = 0;
protected int searchButtonYOffset = 0;
protected int readAllButtonYOffset = 0;

/**
* If this entry is set the book will ignore all other content and just display this entry.
* Note that the entry still needs to be in a valid category, even if the category is not displayed.
*
* The book will be treated as a book in index mode (that means, no big "node view" background will be shown behind the entry).
*/
@Nullable
protected ResourceLocation leafletEntry;

protected BookModel(ResourceLocation id, String name) {
this.id = id;
this.name = name;
Expand Down Expand Up @@ -188,6 +236,10 @@ public BookDisplayMode getDisplayMode() {
return this.displayMode;
}

public @Nullable ResourceLocation getLeafletEntry() {
return this.leafletEntry;
}

public JsonObject toJson(HolderLookup.Provider provider) {
JsonObject json = new JsonObject();
json.addProperty("name", this.name);
Expand Down Expand Up @@ -221,6 +273,11 @@ public JsonObject toJson(HolderLookup.Provider provider) {
if (this.customBookItem != null) {
json.addProperty("custom_book_item", this.customBookItem.toString());
}

if (this.leafletEntry != null) {
json.addProperty("leaflet_entry", this.leafletEntry.toString());
}

return json;
}

Expand Down Expand Up @@ -442,4 +499,13 @@ public BookModel withReadAllButtonYOffset(int readAllButtonYOffset) {
this.readAllButtonYOffset = readAllButtonYOffset;
return this;
}

/**
* If this entry is set the book will ignore all other content and just display this entry.
* Note that the entry still needs to be in a valid category, even if the category is not displayed.
*/
public BookModel withLeafletEntry(ResourceLocation leafletEntry) {
this.leafletEntry = leafletEntry;
return this;
}
}
Loading

0 comments on commit 3e18a8c

Please sign in to comment.