diff --git a/api/src/main/java/ru/dragonestia/msb3/api/talk/dialogue/DialogueRenderer.java b/api/src/main/java/ru/dragonestia/msb3/api/talk/dialogue/DialogueRenderer.java index e4d4c85..761eb4d 100644 --- a/api/src/main/java/ru/dragonestia/msb3/api/talk/dialogue/DialogueRenderer.java +++ b/api/src/main/java/ru/dragonestia/msb3/api/talk/dialogue/DialogueRenderer.java @@ -337,17 +337,17 @@ public class DialogueRenderer extends Inventory { boolean endWithDots = lineIdx + 1 == GlyphPositions.answerText.maxLines() && lineIdx + 1 != lines.size(); var line = lines.get(lineIdx); - builder.append( + builder.setColorTo(switch (number) { + case BUTTON_1 -> theme.getColorAnswerText1(); + case BUTTON_2 -> theme.getColorAnswerText2(); + case BUTTON_3 -> theme.getColorAnswerText3(); + case BUTTON_4 -> theme.getColorAnswerText4(); + }).append( number.getIndex() % 2 == 0 ? GlyphPositions.answerText.leftLineX() : GlyphPositions.answerText.rightLineX(), - line.toGlyphList(line.textureProperties(), 0, endWithDots, switch (number) { - case BUTTON_1 -> theme.getColorAnswerText1(); - case BUTTON_2 -> theme.getColorAnswerText2(); - case BUTTON_3 -> theme.getColorAnswerText3(); - case BUTTON_4 -> theme.getColorAnswerText4(); - }) - ); + line.toGlyphList(line.textureProperties(), 0, endWithDots) + ).resetColor(); } @@ -400,12 +400,12 @@ public class DialogueRenderer extends Inventory { for (int lineIdx = shift; (lineIdx - shift) < Math.min(textLines.size() - shift, GlyphPositions.phraseText.maxLines()); lineIdx++) { var line = textLines.get(lineIdx); - builder.append(GlyphPositions.phraseText.lineX(), line.toGlyphList( - line.textureProperties(), - shift, - textLines.size() - lineIdx > 0 && lineIdx - shift == GlyphPositions.phraseText.maxLines() - 1, - getTheme().getColorText() - )); + builder.setColorTo(getTheme().getColorText()) + .append(GlyphPositions.phraseText.lineX(), line.toGlyphList( + line.textureProperties(), + shift, + textLines.size() - lineIdx > 0 && lineIdx - shift == GlyphPositions.phraseText.maxLines() - 1 + )).resetColor(); } } @@ -440,7 +440,7 @@ public class DialogueRenderer extends Inventory { private record TextLine(DialogueTheme theme, String text, TextureProperties textureProperties) { - public GlyphComponent toGlyphList(TextureProperties parentProperties, int lineShift, boolean cutEnding, TextColor color) { + public GlyphComponent toGlyphList(TextureProperties parentProperties, int lineShift, boolean cutEnding) { var properties = new TextureProperties( parentProperties.height(), parentProperties.ascent() + lineShift * (textureProperties().height() + 1) diff --git a/resource-compiler/src/main/java/ru/dragonestia/msb3/resource/glyph/GlyphComponentBuilder.java b/resource-compiler/src/main/java/ru/dragonestia/msb3/resource/glyph/GlyphComponentBuilder.java index 386c3af..b1d0904 100644 --- a/resource-compiler/src/main/java/ru/dragonestia/msb3/resource/glyph/GlyphComponentBuilder.java +++ b/resource-compiler/src/main/java/ru/dragonestia/msb3/resource/glyph/GlyphComponentBuilder.java @@ -1,8 +1,10 @@ package ru.dragonestia.msb3.resource.glyph; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; import java.util.ArrayList; @@ -16,9 +18,9 @@ import java.util.List; */ public class GlyphComponentBuilder { - private static final Entry NEW_LINE = new Entry(Position.ABSOLUTE, 0, new Text("\n", 0)); + private static final Container NEW_LINE = new Container(EntryType.COMPONENT, new EntryComponent(Position.ABSOLUTE, 0, new Text("\n", 0))); - private final List entries = new ArrayList<>(); + private final List entries = new ArrayList<>(); /** * Добавить компонент после предыдущего компонента @@ -47,7 +49,7 @@ public class GlyphComponentBuilder { * @return Текущий объект билдера */ public GlyphComponentBuilder append(Position position, int offset, GlyphComponent component) { - entries.add(new Entry(position, offset, component)); + entries.add(new Container(EntryType.COMPONENT, new EntryComponent(position, offset, component))); return this; } @@ -63,11 +65,35 @@ public class GlyphComponentBuilder { return this; } + /** + * Установить новый цвет для последующих глифов. Не окрашивает старые компоненты глифов + * + *

Применяется также для цветных изображений. Во избежание неправильного отображения цвета у глифа + * советуется сбрасывать цвет + * + * @param color Цвет + * @return Текущий объект билдера + */ + public GlyphComponentBuilder setColorTo(TextColor color) { + entries.add(new Container(EntryType.COLOR, new EntryColor(color))); + return this; + } + + /** + * Сбросить цветовой код глифов. + * + *

В основном используется, для того чтобы избежать проблемы с отображением цветных глифов + * @return Текущий объект билдера + */ + public GlyphComponentBuilder resetColor() { + return setColorTo(NamedTextColor.WHITE); + } + /** * Собрать все компоненты глифов в один текстовый компонент * @return Текстовый компонент */ - public Component build() { + public TextComponent build() { return build(false); } @@ -76,15 +102,7 @@ public class GlyphComponentBuilder { * @param resetPosition Возвращать ли смещение на начало? * @return Текстовый компонент */ - public Component build(boolean resetPosition) { - var sb = new StringBuilder(); - var text = buildAsGlyphComponent(); - - sb.append(text.content()); - if (resetPosition) { - sb.append(Spacing.getAsString(-text.width())); - } - + public TextComponent build(boolean resetPosition) { var style = Style.style() .color(NamedTextColor.WHITE) .decoration(TextDecoration.ITALIC, false) @@ -93,44 +111,67 @@ public class GlyphComponentBuilder { .decoration(TextDecoration.STRIKETHROUGH, false) .decoration(TextDecoration.OBFUSCATED, false) .build(); - - return Component.text(sb.toString(), style); - } - - /** - * Собрать все компоненты глифов в один компонент глифа - * @return Компонент глифа - */ - public GlyphComponent buildAsGlyphComponent() { - var builder = new StringBuilder(); + var builder = Component.text().style(style); int offset = 0; + TextColor lastColor = NamedTextColor.WHITE; for (var entry: entries) { - var component = entry.glyphComponent; - var val = entry.offset; - switch (entry.position) { - case ABSOLUTE -> { - builder.append(Spacing.getAsString(val - offset)); - offset = val; - } + switch (entry.type()) { + case COMPONENT -> { + var obj = entry.asComponent(); + var component = obj.glyphComponent; + var val = obj.offset; + switch (obj.position) { + case ABSOLUTE -> { + builder.append(Spacing.get(val - offset)); + offset = val; + } - case RELATIVE -> { - if (val == 0) { - builder.append(Spacing.getAsString(val)); + case RELATIVE -> { + if (val == 0) { + builder.append(Spacing.get(val)); + } + offset += val; + } } - offset += val; - } - } - offset += entry.glyphComponent.width() + 1; - builder.append(component.content()); + offset += obj.glyphComponent.width() + 1; + builder.append(Component.text(component.content(), lastColor)); + } + + case COLOR -> lastColor = entry.asColor().color(); + } } - return new Text(builder.toString(), offset); + if (resetPosition) { + builder.append(Spacing.get(-offset)); + } + + return builder.build(); } - private record Entry(Position position, int offset, GlyphComponent glyphComponent) {} + private enum EntryType { + COMPONENT, + COLOR, + } + + private interface Entry {} + + private record EntryComponent(Position position, int offset, GlyphComponent glyphComponent) implements Entry {} + + private record EntryColor(TextColor color) implements Entry {} + + private record Container(EntryType type, Entry obj) { + + EntryComponent asComponent() { + return (EntryComponent) obj; + } + + EntryColor asColor() { + return (EntryColor) obj; + } + } private static class Text implements GlyphComponent {