diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java index 5c95693b..edf637f6 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Stream; import org.jetbrains.annotations.Nullable; @@ -83,6 +84,12 @@ public class TraitDiscovery implements NbtSerialisable { return items.getOrDefault(Registry.ITEM.getId(item), SpellTraits.EMPTY); } + public Stream getKnownItems(Trait trait) { + return items.entrySet().stream() + .filter(entry -> entry.getValue().get(trait) > 0) + .flatMap(entry -> Registry.ITEM.getOrEmpty(entry.getKey()).stream()); + } + public boolean isUnread(Trait trait) { return unreadTraits.contains(trait); } diff --git a/src/main/java/com/minelittlepony/unicopia/container/IngredientTree.java b/src/main/java/com/minelittlepony/unicopia/container/IngredientTree.java index 01d9da4c..ab67ccf5 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/IngredientTree.java +++ b/src/main/java/com/minelittlepony/unicopia/container/IngredientTree.java @@ -26,12 +26,19 @@ class IngredientTree implements SpellbookRecipe.CraftingTreeBuilder { private final int y; private final int width; - public IngredientTree(int x, int y, int width, int height) { + private boolean addLabels = true; + + public IngredientTree(int x, int y, int width) { this.x = x + 4; this.y = y; this.width = width - 5; } + public IngredientTree noLabels() { + addLabels = false; + return this; + } + @Override public void input(ItemStack... stacks) { if (stacks.length > 0) { @@ -76,11 +83,11 @@ class IngredientTree implements SpellbookRecipe.CraftingTreeBuilder { int left = x + column * colWidth + 3 + (row > 0 ? colWidth : 0); int top = y + row * rowHeight + 3; - container.addButton(new IngredientButton(left, top, colWidth, rowHeight, entry, ii == 0 ? "" : "+")); + container.addButton(new IngredientButton(left, top, colWidth, rowHeight, entry, !addLabels || ii == 0 ? "" : "+")); ii++; } result.ifPresent(result -> { - container.addButton(new IngredientButton(x + width - 17, y + totalHeight / 3 - 2, colWidth, totalHeight, result, "=")); + container.addButton(new IngredientButton(x + width - 17, y + totalHeight / 3 - 2, colWidth, totalHeight, result, addLabels ? "=" : "")); }); return totalHeight + 7; diff --git a/src/main/java/com/minelittlepony/unicopia/container/PageElement.java b/src/main/java/com/minelittlepony/unicopia/container/PageElement.java index 94bdb5bd..a006f1cb 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/PageElement.java +++ b/src/main/java/com/minelittlepony/unicopia/container/PageElement.java @@ -148,7 +148,9 @@ interface PageElement extends Drawable { if (recipe instanceof SpellbookRecipe spellRecipe) { IngredientTree tree = new IngredientTree( bounds().left + page().getBounds().left, - bounds().top + page().getBounds().top + y + 10, page().getBounds().width - 20, 20); + bounds().top + page().getBounds().top + y + 10, + page().getBounds().width - 20 + ); spellRecipe.buildCraftingTree(tree); bounds.height = tree.build(container) - 10; } @@ -161,7 +163,9 @@ interface PageElement extends Drawable { public void compile(int y, IViewRoot container) { IngredientTree tree = new IngredientTree( bounds().left + page().getBounds().left, - bounds().top + page().getBounds().top + y + 10, 30, 20); + bounds().top + page().getBounds().top + y + 10, + 30 + ); tree.input(ingredient.getMatchingStacks()); bounds.height = tree.build(container) - 10; } diff --git a/src/main/java/com/minelittlepony/unicopia/container/SpellbookChapterList.java b/src/main/java/com/minelittlepony/unicopia/container/SpellbookChapterList.java index 5355aa42..54037fbe 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/SpellbookChapterList.java +++ b/src/main/java/com/minelittlepony/unicopia/container/SpellbookChapterList.java @@ -13,6 +13,7 @@ import net.minecraft.util.Identifier; public class SpellbookChapterList { public static final Identifier CRAFTING_ID = Unicopia.id("crafting"); public static final Identifier PROFILE_ID = Unicopia.id("profile"); + public static final Identifier TRAIT_DEX_ID = Unicopia.id("traits"); private final Chapter craftingChapter; @@ -20,13 +21,15 @@ public class SpellbookChapterList { private final Map chapters = new HashMap<>(); - public SpellbookChapterList(Chapter craftingChapter, Chapter profileChapter) { + public SpellbookChapterList(Chapter craftingChapter, Chapter... builtIn) { this.craftingChapter = craftingChapter; SpellbookChapterLoader.INSTANCE.getChapters().forEach(chapter -> { chapters.put(chapter.id(), chapter); }); chapters.put(craftingChapter.id(), craftingChapter); - chapters.put(profileChapter.id(), profileChapter); + for (Chapter i : builtIn) { + chapters.put(i.id(), i); + } } public Stream getTabs(TabSide side) { diff --git a/src/main/java/com/minelittlepony/unicopia/container/SpellbookCraftingPageContent.java b/src/main/java/com/minelittlepony/unicopia/container/SpellbookCraftingPageContent.java index 136365d9..24f3b502 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/SpellbookCraftingPageContent.java +++ b/src/main/java/com/minelittlepony/unicopia/container/SpellbookCraftingPageContent.java @@ -10,18 +10,12 @@ import com.minelittlepony.unicopia.container.SpellbookScreen.TraitButton; import com.minelittlepony.unicopia.item.URecipes; import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; -import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; -public class SpellbookCraftingPageContent extends ScrollContainer implements SpellbookChapterList.Content, RecipeBookProvider { - - +public class SpellbookCraftingPageContent extends ScrollContainer implements SpellbookChapterList.Content, SpellbookScreen.RecipesChangedListener { private final SpellbookScreen screen; - private final RecipeBookWidget recipeBook = new RecipeBookWidget(); - public SpellbookCraftingPageContent(SpellbookScreen screen) { this.screen = screen; backgroundColor = 0xFFf9efd3; @@ -31,7 +25,7 @@ public class SpellbookCraftingPageContent extends ScrollContainer implements Spe @Override public void init(SpellbookScreen screen) { screen.addPageButtons(187, 300, 350, SpellbookPage::swap); - refreshRecipeBook(); + initContents(); screen.addDrawable(this); ((IViewRoot)screen).getChildElements().add(this); } @@ -48,13 +42,12 @@ public class SpellbookCraftingPageContent extends ScrollContainer implements Spe } @Override - public void refreshRecipeBook() { - init(this::initPageContent); + public void onRecipesChanged() { + initContents(); } - @Override - public RecipeBookWidget getRecipeBookWidget() { - return recipeBook; + public void initContents() { + init(this::initPageContent); } private void initPageContent() { @@ -85,9 +78,7 @@ public class SpellbookCraftingPageContent extends ScrollContainer implements Spe int top = 0; for (SpellbookRecipe recipe : this.client.world.getRecipeManager().listAllOfType(URecipes.SPELLBOOK)) { if (client.player.getRecipeBook().contains(recipe)) { - IngredientTree tree = new IngredientTree(0, top, - width - scrollbar.getBounds().width + 2, - 20); + IngredientTree tree = new IngredientTree(0, top, width - scrollbar.getBounds().width + 2); recipe.buildCraftingTree(tree); top += tree.build(this); } diff --git a/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreen.java b/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreen.java index b684e449..8ad3260e 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreen.java @@ -42,12 +42,13 @@ public class SpellbookScreen extends HandledScreen imple public static final int TITLE_Y = 20; public static final int TITLE_COLOR = 0xFF404040; - private final SpellbookCraftingPageContent craftingPageWidget = new SpellbookCraftingPageContent(this); + private final RecipeBookWidget recipeBook = new RecipeBookWidget(); - private final Chapter craftingChapter = new Chapter(SpellbookChapterList.CRAFTING_ID, TabSide.LEFT, 0, 0, Optional.of(craftingPageWidget)); + private final Chapter craftingChapter = new Chapter(SpellbookChapterList.CRAFTING_ID, TabSide.LEFT, 0, 0, Optional.of(new SpellbookCraftingPageContent(this))); private final Chapter profileChapter = new Chapter(SpellbookChapterList.PROFILE_ID, TabSide.LEFT, 1, 0, Optional.of(new SpellbookProfilePageContent(this))); + private final Chapter traitdexChapter = new Chapter(SpellbookChapterList.TRAIT_DEX_ID, TabSide.LEFT, 3, 0, Optional.of(new SpellbookTraitDexPageContent(this))); - private final SpellbookChapterList chapters = new SpellbookChapterList(craftingChapter, profileChapter); + private final SpellbookChapterList chapters = new SpellbookChapterList(craftingChapter, profileChapter, traitdexChapter); private final SpellbookTabBar tabs = new SpellbookTabBar(this, chapters); private Bounds contentBounds = Bounds.empty(); @@ -106,12 +107,15 @@ public class SpellbookScreen extends HandledScreen imple @Override public void refreshRecipeBook() { - craftingPageWidget.refreshRecipeBook(); + chapters.getCurrentChapter() + .content() + .map(i -> i instanceof RecipesChangedListener ? (RecipesChangedListener)i : null) + .ifPresent(RecipesChangedListener::onRecipesChanged); } @Override public RecipeBookWidget getRecipeBookWidget() { - return craftingPageWidget.getRecipeBookWidget(); + return recipeBook; } @Override @@ -320,4 +324,8 @@ public class SpellbookScreen extends HandledScreen imple RenderSystem.setShaderColor(1, 1, 1, 1); } } + + public interface RecipesChangedListener { + void onRecipesChanged(); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/container/SpellbookTraitDexPageContent.java b/src/main/java/com/minelittlepony/unicopia/container/SpellbookTraitDexPageContent.java new file mode 100644 index 00000000..8b4c160b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/container/SpellbookTraitDexPageContent.java @@ -0,0 +1,131 @@ +package com.minelittlepony.unicopia.container; + +import com.minelittlepony.common.client.gui.IViewRoot; +import com.minelittlepony.common.client.gui.ScrollContainer; +import com.minelittlepony.common.client.gui.element.Label; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import net.minecraft.util.math.MathHelper; + +public class SpellbookTraitDexPageContent extends DrawableHelper implements SpellbookChapterList.Content, SpellbookScreen.RecipesChangedListener { + + private final Trait[] traits = Trait.all().toArray(Trait[]::new); + private int offset; + + private final DexPage leftPage = new DexPage(); + private final DexPage rightPage = new DexPage(); + + private final SpellbookScreen screen; + + public SpellbookTraitDexPageContent(SpellbookScreen screen) { + this.screen = screen; + } + + @Override + public void draw(MatrixStack matrices, int mouseX, int mouseY, IViewRoot container) { + + } + + @Override + public void init(SpellbookScreen screen) { + int page = offset * 2; + leftPage.init(screen, page); + rightPage.init(screen, page + 1); + screen.addPageButtons(187, 30, 350, incr -> { + offset = MathHelper.clamp(offset + incr, 0, (int)Math.ceil(traits.length / 2F) - 1); + }); + } + + @Override + public void onRecipesChanged() { + init(screen); + } + + private final class DexPage extends ScrollContainer { + public DexPage() { + scrollbar.layoutToEnd = true; + backgroundColor = 0xFFf9efd3; + } + + public void init(SpellbookScreen screen, int page) { + if (page < 0 || page >= traits.length) { + return; + } + + margin.left = screen.getX() + 20; + margin.top = screen.getY() + 15; + margin.right = screen.width - screen.getBackgroundWidth() - screen.getX() + 20; + margin.bottom = screen.height - screen.getBackgroundHeight() - screen.getY() + 40; + + if (page % 2 == 1) { + margin.left += screen.getBackgroundWidth() / 2; + } else { + margin.right += screen.getBackgroundWidth() / 2 - 5; + } + + init(() -> { + Trait trait = traits[page]; + + boolean known = Pony.of(MinecraftClient.getInstance().player).getDiscoveries().isKnown(trait); + + addButton(new SpellbookScreen.TraitButton(width / 2 - 8, 8, trait)); + addButton(new Label(width / 2, 26).setCentered()) + .getStyle() + .setText(known ? Text.translatable("gui.unicopia.trait.label", + Text.translatable("trait." + trait.getId().getNamespace() + "." + trait.getId().getPath() + ".name") + ) : Text.literal("???")); + IngredientTree tree = new IngredientTree(0, 50, width).noLabels(); + Pony.of(MinecraftClient.getInstance().player).getDiscoveries().getKnownItems(trait).forEach(i -> tree.input(i.getDefaultStack())); + tree.build(this); + }); + screen.addDrawable(this); + ((IViewRoot)screen).getChildElements().add(this); + } + + + @Override + public void drawOverlays(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) { + matrices.push(); + matrices.translate(margin.left, margin.top, 0); + matrices.translate(-2, -2, 0); + RenderSystem.enableBlend(); + RenderSystem.setShaderTexture(0, SpellbookScreen.TEXTURE); + int tileSize = 25; + + final int bottom = height - tileSize + 4; + final int right = width - tileSize + 9; + + drawTexture(matrices, 0, 0, 405, 62, tileSize, tileSize, 512, 256); + drawTexture(matrices, right, 0, 425, 62, tileSize, tileSize, 512, 256); + + drawTexture(matrices, 0, bottom, 405, 72, tileSize, tileSize, 512, 256); + drawTexture(matrices, right, bottom, 425, 72, tileSize, tileSize, 512, 256); + + for (int i = tileSize; i < right; i += tileSize) { + drawTexture(matrices, i, 0, 415, 62, tileSize, tileSize, 512, 256); + drawTexture(matrices, i, bottom, 415, 72, tileSize, tileSize, 512, 256); + } + + for (int i = tileSize; i < bottom; i += tileSize) { + drawTexture(matrices, 0, i, 405, 67, tileSize, tileSize, 512, 256); + drawTexture(matrices, right, i, 425, 67, tileSize, tileSize, 512, 256); + } + matrices.pop(); + + if (this == rightPage) { + leftPage.drawDelayed(matrices, mouseX, mouseY, 0); + rightPage.drawDelayed(matrices, mouseX, mouseY, 0); + } + } + + public void drawDelayed(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) { + super.drawOverlays(matrices, mouseX, mouseY, tickDelta); + } + } +}