Skip to content

Commit

Permalink
feat: allow books or individual categories to use "index" mode (patch…
Browse files Browse the repository at this point in the history
…ouli style books) (#214)

* feat: first experiments with index-based books

* feat: add basic category index view

* chore: refactor structure and rename classes to unified scheme

* chore: add missing annotations

* chore: adjust wrong renames

* feat: add display mode property to book and category

* chore: state management refactor

* chore: run datagen

* chore: state management refactor

* chore: remove test code

* chore: state management refactor

* feat: re-add open entry and category link entry functionality

* chore: refactor closing handling

* chore: rename onEsc to closeScreenStack to better reflect its role

* chore: minor code cleanup

* fix: book always reopens entry/category even if not closed with esc

* feat: set up new direct-to-entry navigation

* chore: remove completed todo

* chore: reorganize methods in gui manager and add index mode open logic

* feat: add index book state loading/saving

* feat: extend index mode handling

* fix: each category displays all book entries

* feat: add background rendering handling for index categories in node parents

* feat: add behaviour handling for index categories in node parents

* chore: code cleanup

* feat: add descriptions to book and category

* chore: restructure book package

* chore: re-establish reuse compliance

* feat: add layered gui for fabric

* feat: add search button to index parent screen

* feat: add read all button

* chore: remove complete todo comments

* fix: commands on fabric

* feat: add sort number handling to datagen
  • Loading branch information
klikli-dev authored Jun 13, 2024
1 parent 78326d0 commit e245bde
Show file tree
Hide file tree
Showing 149 changed files with 2,992 additions and 1,057 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ public static class Gui {
public static final String SEARCH_INFO_TEXT = PREFIX + "search.info";
public static final String SEARCH_ENTRY_LIST_TITLE = PREFIX + "search.entry_list_title";

public static final String BOOK_INDEX_LIST_TITLE = PREFIX + "book.index_list_title";
public static final String CATEGORY_INDEX_LIST_TITLE = PREFIX + "category.index_list_title";


public static final String OPEN_SEARCH = PREFIX + "open_search";

public static final String RECIPE_PAGE_RECIPE_MISSING = PREFIX + "recipe_page.recipe_missing";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ public String bookName() {
return this.book() + ".name";
}

public String bookDescription() {
return this.book() + ".description";
}

public String bookTooltip() {
return this.book() + ".tooltip";
}
Expand Down Expand Up @@ -87,6 +91,10 @@ public String categoryName() {
return this.category() + ".name";
}

public String categoryDescription() {
return this.category() + ".description";
}

public String categoryCondition(String conditionName) {
return this.category() + ".condition." + conditionName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.slf4j.Logger;

import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collector;
Expand All @@ -30,8 +31,6 @@

public abstract class BookProvider implements DataProvider {

protected static final Logger LOGGER = LogUtils.getLogger();

public static final Collector<ModonomiconLanguageProvider, ?, Object2ObjectOpenHashMap<String, ModonomiconLanguageProvider>> mapMaker
= Collector.<ModonomiconLanguageProvider, Object2ObjectOpenHashMap<String, ModonomiconLanguageProvider>, Object2ObjectOpenHashMap<String, ModonomiconLanguageProvider>>of(
Object2ObjectOpenHashMap::new,
Expand All @@ -46,30 +45,34 @@ public abstract class BookProvider implements DataProvider {
protected final ModonomiconLanguageProvider lang;
protected final Map<String, ModonomiconLanguageProvider> translations;
protected final Map<ResourceLocation, BookModel> bookModels;
protected BookModel bookModel;
protected final String modid;
protected String bookId;
protected BookContextHelper context;

protected Map<String, String> defaultMacros;

protected ConditionHelper conditionHelper;
protected int currentSortIndex;

/**
* @param defaultLang The LanguageProvider to fill with this book provider. IMPORTANT: the Languag Provider needs to be added to the DataGenerator AFTER the BookProvider.
* @param defaultLang The LanguageProvider to fill with this book provider. IMPORTANT: the Language Provider needs to be added to the DataGenerator AFTER the BookProvider.
*/
public BookProvider(String bookId, PackOutput packOutput, CompletableFuture<HolderLookup.Provider> registries, String modid, ModonomiconLanguageProvider defaultLang, ModonomiconLanguageProvider... translations) {
this.modid = modid;
this.packOutput = packOutput;
this.registries = registries;
this.lang = defaultLang;
this.bookModels = new Object2ObjectOpenHashMap<>();
this.bookModel = null;
this.translations = Stream.concat(Arrays.stream(translations), Stream.of(defaultLang))
.collect(mapMaker);

this.bookId = bookId;
this.context = new BookContextHelper(this.modid);
this.defaultMacros = new Object2ObjectOpenHashMap<>();
this.conditionHelper = new ConditionHelper();
this.currentSortIndex = 0;
}

protected ModonomiconLanguageProvider lang() {
Expand All @@ -92,18 +95,6 @@ protected ConditionHelper condition() {
return this.conditionHelper;
}

/**
* Call registerMacro() here to make macros (= simple string.replace() of macro -> value) available to all category providers of this book.
*/
protected abstract void registerDefaultMacros();

/**
* Override this to generate your book.
* Each BookProvider should generate only one book.
* Context already is set to the book id provided in the constructor.
*/
protected abstract BookModel generateBook();

/**
* Register a macro (= simple string.replace() of macro -> value) to be used in all category providers of this book.
*/
Expand All @@ -122,15 +113,25 @@ protected Map<String, String> defaultMacros() {
* Only override if you know what you are doing.
* Generally you should not.
*/
protected void generate() {
this.context.book(this.bookId);
this.add(this.generateBook());
public void generate() {
this.context().book(this.bookId);
this.bookModel = this.generateBook();
this.generateCategories();
this.add(this.bookModel);
}

protected ResourceLocation modLoc(String name) {
return ResourceLocation.fromNamespaceAndPath(this.modid, name);
}

protected BookCategoryModel add(BookCategoryModel category) {
if(category.getSortNumber() == -1){
category.withSortNumber(this.currentSortIndex++);
}
this.bookModel.withCategory(category);
return category;
}

protected BookModel add(BookModel bookModel) {
if (this.bookModels.containsKey(bookModel.getId()))
throw new IllegalStateException("Duplicate book " + bookModel.getId());
Expand Down Expand Up @@ -176,6 +177,59 @@ protected Path getPath(Path dataFolder, BookEntryModel bookEntryModel) {
.resolve(id.getPath() + ".json");
}

/**
* Add translation to the default translation provider.
* This will apply all macros registered in this category provider and its parent book provider.
*/
protected void add(String key, String value) {
this.lang().add(key, this.macro(value));
}

/**
* Adds translation to the default translation provider with a pattern and arguments, internally using MessageFormat to format the pattern.
* This will apply all macros registered in this category provider and its parent book provider.
*/
protected void add(String key, String pattern, Object... args) {
this.add(key, this.format(pattern, args));
}

/**
* Add translation to the given translation provider.
* This will apply all macros registered in this category provider and its parent book provider.
* <p>
* Sample usage: this.add(this.lang("ru_ru"), "category", "Text");
*/
protected void add(ModonomiconLanguageProvider translation, String key, String value) {
translation.add(key, this.macro(value));
}

/**
* Adds translation to the given translation provider with a pattern and arguments, internally using MessageFormat to format the pattern.
* This will apply all macros registered in this category provider and its parent book provider.
* <p>
* Sample usage: this.add(this.lang("ru_ru"), "category", "pattern", "arg1");
*/
protected void add(ModonomiconLanguageProvider translation, String key, String pattern, Object... args) {
this.add(translation, key, this.format(pattern, args));
}

/**
* Apply all macros of this book provider to the input string.
*/
protected String macro(String input) {
for (var entry : this.defaultMacros().entrySet()) {
input = input.replace(entry.getKey(), entry.getValue());
}
return input;
}

/**
* Format a string with the given arguments using MessageFormat.format()
*/
protected String format(String pattern, Object... arguments) {
return MessageFormat.format(pattern, arguments);
}

@Override
public CompletableFuture<?> run(CachedOutput cache) {
return this.registries.thenCompose(registries -> {
Expand Down Expand Up @@ -215,4 +269,22 @@ public String getName() {
return "Books: " + this.modid;
}

/**
* Call registerMacro() here to make macros (= simple string.replace() of macro -> value) available to all category providers of this book.
*/
protected abstract void registerDefaultMacros();

/**
* Implement this and return your book.
* Categories should not be added here, instead call .add() in generateCategories().
* Context already is set to this book.
*/
protected abstract BookModel generateBook();

/**
* Implement this and in it generate and .add() your categories.
* Context already is set to this book.
*/
protected abstract void generateCategories();

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public abstract class CategoryProvider {
protected ConditionHelper conditionHelper;

protected BookCategoryModel category;
protected int currentSortIndex;


public CategoryProvider(BookProvider parent, String categoryId) {
this.parent = parent;
Expand All @@ -43,6 +45,7 @@ public CategoryProvider(BookProvider parent, String categoryId) {
this.macros = new Object2ObjectOpenHashMap<>();
this.conditionHelper = new ConditionHelper();
this.category = null;
this.currentSortIndex = 0;
}

public String categoryId() {
Expand Down Expand Up @@ -260,7 +263,7 @@ protected void add(String key, String value) {
* <p>
* Sample usage: this.add(this.lang("ru_ru"), "category", "Text");
*/
protected void add(AbstractModonomiconLanguageProvider translation, String key, String value) {
protected void add(ModonomiconLanguageProvider translation, String key, String value) {
translation.add(key, this.macro(value));
}

Expand All @@ -278,16 +281,24 @@ protected void add(String key, String pattern, Object... args) {
* <p>
* Sample usage: this.add(this.lang("ru_ru"), "category", "pattern", "arg1");
*/
protected void add(AbstractModonomiconLanguageProvider translation, String key, String pattern, Object... args) {
protected void add(ModonomiconLanguageProvider translation, String key, String pattern, Object... args) {
this.add(translation, key, this.format(pattern, args));
}

protected BookEntryModel add(BookEntryModel entry) {
if(entry.getSortNumber() == -1){
entry.withSortNumber(this.currentSortIndex++);
}
this.category.withEntry(entry);
return entry;
}

protected List<BookEntryModel> add(List<BookEntryModel> entries) {
for (var entry : entries) {
if(entry.getSortNumber() == -1){
entry.withSortNumber(this.currentSortIndex++);
}
}
this.category.withEntries(entries);
return entries;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
import com.google.gson.JsonObject;
import com.klikli_dev.modonomicon.api.ModonomiconConstants.Data.Category;
import com.klikli_dev.modonomicon.api.datagen.book.condition.BookConditionModel;
import com.klikli_dev.modonomicon.api.datagen.book.page.BookTextPageModel;
import com.klikli_dev.modonomicon.book.BookCategoryBackgroundParallaxLayer;
import com.klikli_dev.modonomicon.book.BookDisplayMode;
import com.klikli_dev.modonomicon.registry.ItemRegistry;
import com.mojang.serialization.JsonOps;
import net.minecraft.core.HolderLookup;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.ItemLike;
import org.jetbrains.annotations.Nullable;
Expand All @@ -26,7 +29,17 @@ public class BookCategoryModel {

protected ResourceLocation id;
protected String name;
/**
* The description to (optionally) display on the first page of the category.
*/
protected BookTextHolderModel description = new BookTextHolderModel("");
protected BookIconModel icon = BookIconModel.create(ItemRegistry.MODONOMICON_PURPLE.get());

/**
* The display mode - node based (thaumonomicon style) or index based (lexica botania / patchouli style)
*/
protected BookDisplayMode displayMode = BookDisplayMode.NODE;

protected int sortNumber = -1;
protected ResourceLocation background = ResourceLocation.parse(Category.DEFAULT_BACKGROUND);
protected int backgroundWidth = Category.DEFAULT_BACKGROUND_WIDTH;
Expand Down Expand Up @@ -89,7 +102,9 @@ public BookModel getBook() {
public JsonObject toJson(HolderLookup.Provider provider) {
JsonObject json = new JsonObject();
json.addProperty("name", this.name);
json.add("description", this.description.toJson(provider));
json.add("icon", this.icon.toJson(provider));
json.addProperty("display_mode", this.displayMode.getSerializedName());
json.addProperty("sort_number", this.sortNumber);
json.addProperty("background", this.background.toString());
json.addProperty("background_width", this.backgroundWidth);
Expand Down Expand Up @@ -120,10 +135,18 @@ public String getName() {
return this.name;
}

public BookTextHolderModel getDescription() {
return this.description;
}

public BookIconModel getIcon() {
return this.icon;
}

public BookDisplayMode getDisplayMode() {
return this.displayMode;
}

public int getSortNumber() {
return this.sortNumber;
}
Expand All @@ -148,6 +171,22 @@ public ResourceLocation getEntryTextures() {
return this.entryTextures;
}

/**
* The description to (optionally) display on the first page of the category.
*/
public BookCategoryModel withDescription(String title) {
this.description = new BookTextHolderModel(title);
return this;
}

/**
* The description to (optionally) display on the first page of the category.
*/
public BookCategoryModel withDescription(Component title) {
this.description = new BookTextHolderModel(title);
return this;
}

/**
* Sets the category's icon.
*
Expand Down Expand Up @@ -181,6 +220,15 @@ public BookCategoryModel withIcon(ItemLike item) {
return this;
}

/**
* Sets the display mode - node based (thaumonomicon style) or index based (lexica botania / patchouli style)
*/
public BookCategoryModel withDisplayMode(BookDisplayMode displayMode) {
this.displayMode = displayMode;
return this;
}


/**
* Sets the category's sort number.
* Categories with a lower sort number will be displayed first.
Expand Down
Loading

0 comments on commit e245bde

Please sign in to comment.