Add an index to show discovered traits and which items map to those traits

This commit is contained in:
Sollace 2022-09-10 01:29:03 +02:00
parent 8746ea5aae
commit aba1337774
7 changed files with 179 additions and 28 deletions

View file

@ -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<Item> 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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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<Identifier, Chapter> 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<Chapter> getTabs(TabSide side) {

View file

@ -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);
}

View file

@ -42,12 +42,13 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> 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<SpellbookScreenHandler> 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<SpellbookScreenHandler> imple
RenderSystem.setShaderColor(1, 1, 1, 1);
}
}
public interface RecipesChangedListener {
void onRecipesChanged();
}
}

View file

@ -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);
}
}
}