mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 06:26:43 +01:00
Fix some more text wrapping issues and catch exceptions whilst loading chapters
This commit is contained in:
parent
5256f1f273
commit
37148fad51
5 changed files with 76 additions and 39 deletions
|
@ -2,8 +2,7 @@ package com.minelittlepony.unicopia.container;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.*;
|
||||
import com.minelittlepony.common.client.gui.IViewRoot;
|
||||
import com.minelittlepony.common.client.gui.dimension.Bounds;
|
||||
import com.minelittlepony.unicopia.client.gui.DrawableUtil;
|
||||
|
@ -25,8 +24,8 @@ public class DynamicContent implements Content {
|
|||
|
||||
private Bounds bounds = Bounds.empty();
|
||||
|
||||
public DynamicContent(JsonArray pages) {
|
||||
pages.forEach(page -> this.pages.add(new Page(page.getAsJsonObject())));
|
||||
public DynamicContent(JsonArray json) {
|
||||
json.forEach(element -> pages.add(new Page(element.getAsJsonObject())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -36,8 +35,10 @@ public class DynamicContent implements Content {
|
|||
getPage(pageIndex).ifPresent(page -> page.draw(matrices, mouseX, mouseY, container));
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(bounds.width / 2 + 20, 0, 0);
|
||||
getPage(pageIndex + 1).ifPresent(page -> page.draw(matrices, mouseX, mouseY, container));
|
||||
getPage(pageIndex + 1).ifPresent(page -> {
|
||||
page.bounds.left = bounds.left + bounds.width / 2 + 20;
|
||||
page.draw(matrices, mouseX, mouseY, container);
|
||||
});
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
|
@ -45,7 +46,7 @@ public class DynamicContent implements Content {
|
|||
public void copyStateFrom(Content old) {
|
||||
if (old instanceof DynamicContent o) {
|
||||
offset = o.offset;
|
||||
bounds = o.bounds;
|
||||
setBounds(o.bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,10 +57,18 @@ public class DynamicContent implements Content {
|
|||
return Optional.of(pages.get(index));
|
||||
}
|
||||
|
||||
private void setBounds(Bounds bounds) {
|
||||
this.bounds = bounds;
|
||||
pages.forEach(page -> {
|
||||
page.reset();
|
||||
page.bounds.copy(bounds);
|
||||
page.bounds.width /= 2;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(SpellbookScreen screen) {
|
||||
bounds = screen.getFrameBounds();
|
||||
pages.forEach(Page::reset);
|
||||
setBounds(screen.getFrameBounds());
|
||||
screen.addPageButtons(187, 30, 350, incr -> {
|
||||
offset = MathHelper.clamp(offset + incr, 0, (int)Math.ceil(pages.size() / 2F) - 1);
|
||||
});
|
||||
|
@ -73,6 +82,8 @@ public class DynamicContent implements Content {
|
|||
|
||||
private boolean compiled;
|
||||
|
||||
private Bounds bounds = Bounds.empty();
|
||||
|
||||
public Page(JsonObject json) {
|
||||
title = Text.Serializer.fromJson(json.get("title"));
|
||||
level = JsonHelper.getInt(json, "level", 0);
|
||||
|
@ -82,7 +93,7 @@ public class DynamicContent implements Content {
|
|||
}
|
||||
|
||||
protected int getLineLimitAt(int yPosition) {
|
||||
return (bounds.width / 2 - 10) - elements.stream()
|
||||
return (bounds.width - 10) - elements.stream()
|
||||
.filter(PageElement::isFloating)
|
||||
.map(PageElement::bounds)
|
||||
.filter(b -> b.contains(b.left + b.width / 2, yPosition))
|
||||
|
@ -113,6 +124,11 @@ public class DynamicContent implements Content {
|
|||
|
||||
@Override
|
||||
public void draw(MatrixStack matrices, int mouseX, int mouseY, IViewRoot container) {
|
||||
|
||||
if (elements.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!compiled) {
|
||||
compiled = true;
|
||||
int relativeY = 0;
|
||||
|
|
|
@ -54,7 +54,7 @@ interface PageElement extends Drawable {
|
|||
);
|
||||
}
|
||||
if (el.has("recipe")) {
|
||||
return new Recipe(page, new Identifier(JsonHelper.getString(el, "texture")), new Bounds(0, 0, 0, 30));
|
||||
return new Recipe(page, new Identifier(JsonHelper.getString(el, "recipe")), new Bounds(0, 0, 0, 0));
|
||||
}
|
||||
return new TextBlock(page, Text.Serializer.fromJson(element));
|
||||
}
|
||||
|
@ -86,11 +86,10 @@ interface PageElement extends Drawable {
|
|||
@Override
|
||||
public void compile(int y, IViewRoot container) {
|
||||
wrappedText.clear();
|
||||
ParagraphWrappingVisitor visitor = new ParagraphWrappingVisitor(yPosition -> {
|
||||
return page.getLineLimitAt(y + yPosition);
|
||||
}, (line, yPosition) -> {
|
||||
wrappedText.add(new Line(line, page.getLeftMarginAt(y + yPosition)));
|
||||
});
|
||||
ParagraphWrappingVisitor visitor = new ParagraphWrappingVisitor(
|
||||
yPosition -> page.getLineLimitAt(y + yPosition),
|
||||
(line, yPosition) -> wrappedText.add(new Line(line, page.getLeftMarginAt(y + yPosition)))
|
||||
);
|
||||
unwrappedText.visit(visitor, Style.EMPTY);
|
||||
visitor.forceAdvance();
|
||||
bounds.height = MinecraftClient.getInstance().textRenderer.fontHeight * (wrappedText.size());
|
||||
|
@ -128,12 +127,18 @@ interface PageElement extends Drawable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void compile(int y, IViewRoot Container) {
|
||||
public void compile(int y, IViewRoot container) {
|
||||
if (container instanceof SpellbookScreen book) {
|
||||
bounds().left = book.getX();
|
||||
bounds().top = book.getY();
|
||||
}
|
||||
MinecraftClient.getInstance().world.getRecipeManager().get(id).ifPresent(recipe -> {
|
||||
if (recipe instanceof SpellbookRecipe spellRecipe) {
|
||||
IngredientTree tree = new IngredientTree(page.getBounds().left, y, page().getBounds().width / 2 - 20, 20);
|
||||
IngredientTree tree = new IngredientTree(
|
||||
bounds().left + page().getBounds().left,
|
||||
bounds().top + page().getBounds().top + y + 10, page().getBounds().width - 20, 20);
|
||||
spellRecipe.buildCraftingTree(tree);
|
||||
bounds.height = tree.build(Container);
|
||||
bounds.height = tree.build(container) - 10;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class ParagraphWrappingVisitor implements StyledVisitor<Object> {
|
|||
int newline = s.indexOf('\n');
|
||||
|
||||
if (newline >= 0 && newline < trimmedLength) {
|
||||
trimmedLength = newline;
|
||||
trimmedLength = newline + 1;
|
||||
} else {
|
||||
newline = -1;
|
||||
}
|
||||
|
@ -49,17 +49,23 @@ class ParagraphWrappingVisitor implements StyledVisitor<Object> {
|
|||
trimmedLength = s.length();
|
||||
}
|
||||
|
||||
String wrappedFragment = s.substring(0, trimmedLength);
|
||||
int lastSpace = wrappedFragment.lastIndexOf(' ');
|
||||
trimmedLength = lastSpace > 0 ? Math.min(lastSpace, trimmedLength) : trimmedLength;
|
||||
// avoid breaking in the middle of a word
|
||||
if (trimmedLength < s.length() - 1 && trimmedLength > 0
|
||||
&& (!Character.isWhitespace(s.charAt(trimmedLength + 1)) || !Character.isWhitespace(s.charAt(trimmedLength - 1)))) {
|
||||
String wrappedFragment = s.substring(0, trimmedLength);
|
||||
int lastSpace = wrappedFragment.lastIndexOf(' ');
|
||||
trimmedLength = lastSpace > 0 ? Math.min(lastSpace, trimmedLength) : trimmedLength;
|
||||
}
|
||||
|
||||
Text fragment = Text.literal(s.substring(0, trimmedLength).trim()).setStyle(style);
|
||||
float grabbedWidth = handler.getWidth(fragment);
|
||||
|
||||
// advance if appending the next segment would cause an overflow
|
||||
if (currentLineCollectedLength + grabbedWidth > pageWidth) {
|
||||
advance();
|
||||
}
|
||||
|
||||
// append the segment to the line that's being built
|
||||
if (currentLineCollectedLength > 0) {
|
||||
currentLine.append(" ");
|
||||
currentLineCollectedLength += handler.getWidth(" ");
|
||||
|
@ -67,6 +73,10 @@ class ParagraphWrappingVisitor implements StyledVisitor<Object> {
|
|||
currentLine.append(fragment);
|
||||
currentLineCollectedLength += grabbedWidth;
|
||||
|
||||
if (newline >= 0) {
|
||||
advance();
|
||||
}
|
||||
|
||||
if (trimmedLength <= s.length()) {
|
||||
s = s.substring(trimmedLength, s.length());
|
||||
}
|
||||
|
|
|
@ -4,10 +4,13 @@ import java.util.*;
|
|||
import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.container.SpellbookChapterList.*;
|
||||
import com.minelittlepony.unicopia.util.Resources;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -17,10 +20,10 @@ import net.minecraft.util.*;
|
|||
import net.minecraft.util.profiler.Profiler;
|
||||
|
||||
public class SpellbookChapterLoader extends JsonDataLoader implements IdentifiableResourceReloadListener {
|
||||
|
||||
public static boolean DEBUG = true;
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Identifier ID = Unicopia.id("spellbook/chapters");
|
||||
private static final Executor EXECUTOR = CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS);
|
||||
public static boolean DEBUG = true;
|
||||
|
||||
public static final SpellbookChapterLoader INSTANCE = new SpellbookChapterLoader();
|
||||
|
||||
|
@ -39,20 +42,22 @@ public class SpellbookChapterLoader extends JsonDataLoader implements Identifiab
|
|||
return new HashSet<>(chapters.values());
|
||||
}
|
||||
|
||||
private static final Executor EXECUTOR = CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS);
|
||||
|
||||
@Override
|
||||
protected void apply(Map<Identifier, JsonElement> data, ResourceManager manager, Profiler profiler) {
|
||||
chapters = data.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
|
||||
JsonObject json = JsonHelper.asObject(entry.getValue(), "root");
|
||||
try {
|
||||
chapters = data.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
|
||||
JsonObject json = JsonHelper.asObject(entry.getValue(), "root");
|
||||
|
||||
return new Chapter(entry.getKey(),
|
||||
TabSide.valueOf(JsonHelper.getString(json, "side")),
|
||||
JsonHelper.getInt(json, "y_position"),
|
||||
JsonHelper.getInt(json, "color", 0),
|
||||
loadContent(JsonHelper.getObject(json, "content", new JsonObject()))
|
||||
);
|
||||
}));
|
||||
return new Chapter(entry.getKey(),
|
||||
TabSide.valueOf(JsonHelper.getString(json, "side")),
|
||||
JsonHelper.getInt(json, "y_position"),
|
||||
JsonHelper.getInt(json, "color", 0),
|
||||
loadContent(JsonHelper.getObject(json, "content", new JsonObject()))
|
||||
);
|
||||
}));
|
||||
} catch (IllegalStateException | JsonParseException e) {
|
||||
LOGGER.error("Could not load spellbook chapters due to exception", e);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
|
|
|
@ -64,13 +64,14 @@ public class SpellbookProfilePageContent extends DrawableHelper implements Spell
|
|||
float alphaF = (MathHelper.sin(delta / 9F) + 1) / 2F;
|
||||
int alpha = (int)(alphaF * 0x10) & 0xFF;
|
||||
int color = 0x10404000 | alpha;
|
||||
int xpColor = 0xAA0040FF | ((int)(xpPercentage * 0xFF) & 0xFF) << 16;
|
||||
int xpColor = 0xAA0040FF | ((int)((0.3F + 0.7F * xpPercentage) * 0xFF) & 0xFF) << 16;
|
||||
int manaColor = 0xFF00F040 | (int)((0.3F + 0.7F * alphaF) * 0x40) << 16;
|
||||
|
||||
DrawableUtil.drawArc(matrices, 0, radius + 24, 0, DrawableUtil.TAU, color, false);
|
||||
DrawableUtil.drawArc(matrices, radius / 3, radius + 6, 0, DrawableUtil.TAU, color, false);
|
||||
DrawableUtil.drawArc(matrices, radius / 3, radius + 6, 0, xpPercentage * DrawableUtil.TAU, xpColor, false);
|
||||
radius += 8;
|
||||
DrawableUtil.drawArc(matrices, radius, radius + 6 + growth, 0, manaPercentage * DrawableUtil.TAU, 0xFF40F040, false);
|
||||
DrawableUtil.drawArc(matrices, radius, radius + 6 + growth, 0, manaPercentage * DrawableUtil.TAU, manaColor, false);
|
||||
|
||||
String manaString = (int)reserves.getMana().get() + "/" + (int)reserves.getMana().getMax();
|
||||
|
||||
|
|
Loading…
Reference in a new issue