feat: implemented themes for monologues
This commit is contained in:
parent
f46ce9b5be
commit
dd4e1b17f1
@ -0,0 +1,101 @@
|
||||
package ru.dragonestia.msb3.api.resource;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.ImageGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.GlyphResourcePack;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.ResourceIdentifier;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.StringIdentifier;
|
||||
import ru.dragonestia.msb3.api.util.ResourceFromJar;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MonologueResources {
|
||||
|
||||
private static final Key MONOLOG_FONT_KEY = Key.key("msb3", "monolog");
|
||||
public static final String DEFAULT = "default";
|
||||
|
||||
private final GlyphResourcePack glyphResourcePack;
|
||||
private final Map<String, GlyphEntry> avatars = new HashMap<>();
|
||||
private final Map<String, GlyphEntry> frames = new HashMap<>();
|
||||
private final GlyphEntry speechIndicator = initSpeechIndicator();
|
||||
|
||||
public MonologueResources(GlyphResourcePack glyphResourcePack) {
|
||||
this.glyphResourcePack = glyphResourcePack;
|
||||
|
||||
registerAvatar(DEFAULT, ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/monologue/default_avatar.png"));
|
||||
registerFrame(DEFAULT, ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/monologue/avatar_frame.png"));
|
||||
}
|
||||
|
||||
private GlyphEntry initSpeechIndicator() {
|
||||
var writable = ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/monologue/speech_indicator.png");
|
||||
var glyph = ImageGlyph.of(MONOLOG_FONT_KEY,
|
||||
Texture.texture().key(Key.key("msb3", "monolog/speech_indicator.png")).data(writable).build(),
|
||||
new TextureProperties(8, 6));
|
||||
var glyphIdentifier = StringIdentifier.image("monolog_speech_indicator");
|
||||
|
||||
return new GlyphEntry(glyphIdentifier, glyph);
|
||||
}
|
||||
|
||||
public void registerAvatar(String identifier, Writable writable) {
|
||||
var glyph = ImageGlyph.of(MONOLOG_FONT_KEY,
|
||||
Texture.texture().key(Key.key("msb3", "monolog/avatar_" + identifier + ".png")).data(writable).build(),
|
||||
new TextureProperties(42, 2));
|
||||
|
||||
var glyphIdentifier = StringIdentifier.image("monolog_avatar_" + identifier);
|
||||
|
||||
avatars.put(identifier, new GlyphEntry(glyphIdentifier, glyph));
|
||||
|
||||
glyphResourcePack.with(glyphIdentifier, glyph);
|
||||
}
|
||||
|
||||
public void registerFrame(String identifier, Writable writable) {
|
||||
var glyph = ImageGlyph.of(MONOLOG_FONT_KEY,
|
||||
Texture.texture().key(Key.key("msb3", "monolog/frame_" + identifier + ".png")).data(writable).build(),
|
||||
new TextureProperties(50, 6));
|
||||
|
||||
var glyphIdentifier = StringIdentifier.image("monolog_frame_" + identifier);
|
||||
|
||||
frames.put(identifier, new GlyphEntry(glyphIdentifier, glyph));
|
||||
|
||||
glyphResourcePack.with(glyphIdentifier, glyph);
|
||||
}
|
||||
|
||||
public Optional<ImageGlyph> getAvatar(String identifier) {
|
||||
return Optional.ofNullable(avatars.get(identifier))
|
||||
.map(entry -> {
|
||||
try {
|
||||
return glyphResourcePack.get(entry.identifier());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<ImageGlyph> getFrame(String identifier) {
|
||||
return Optional.ofNullable(frames.get(identifier))
|
||||
.map(entry -> {
|
||||
try {
|
||||
return glyphResourcePack.get(entry.identifier());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ImageGlyph getSpeechIndicator() {
|
||||
return glyphResourcePack.get(speechIndicator.identifier());
|
||||
}
|
||||
|
||||
public void compile(GlyphResourcePack resourcePack) {
|
||||
resourcePack.with(speechIndicator.identifier(), speechIndicator.glyph());
|
||||
}
|
||||
|
||||
private record GlyphEntry(ResourceIdentifier<@NotNull ImageGlyph> identifier, ImageGlyph glyph) {}
|
||||
}
|
||||
@ -7,7 +7,6 @@ import ru.dragonestia.msb3.api.glyph.compile.GlyphCompiler;
|
||||
import ru.dragonestia.msb3.api.glyph.font.GlyphFont;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.GlyphResourcePack;
|
||||
import ru.dragonestia.msb3.api.item.BlankSlotItem;
|
||||
import ru.dragonestia.msb3.api.talk.MonologueRenderer;
|
||||
import ru.dragonestia.msb3.api.title.BlackScreen;
|
||||
import team.unnamed.creative.ResourcePack;
|
||||
import team.unnamed.creative.atlas.Atlas;
|
||||
@ -26,6 +25,7 @@ public class ResourcePackManager {
|
||||
|
||||
private final ResourcePack resourcePack;
|
||||
private final GlyphResourcePack glyphResourcePack;
|
||||
private final MonologueResources monologueResources;
|
||||
|
||||
public ResourcePackManager() {
|
||||
resourcePack = ResourcePack.resourcePack();
|
||||
@ -34,6 +34,7 @@ public class ResourcePackManager {
|
||||
resourcePack.unknownFile("credits.txt", Writable.stringUtf8("dragonestia.ru"));
|
||||
|
||||
glyphResourcePack = GlyphResourcePack.create();
|
||||
monologueResources = new MonologueResources(glyphResourcePack);
|
||||
initDefaultGlyphs();
|
||||
}
|
||||
|
||||
@ -42,7 +43,7 @@ public class ResourcePackManager {
|
||||
glyphResourcePack.with(BlankSlotItem.compile());
|
||||
glyphResourcePack.with(GlyphCompiler.instance().compile(BlackScreen.GLYPH));
|
||||
glyphResourcePack.with(GlyphFont.compile());
|
||||
MonologueRenderer.compile(glyphResourcePack);
|
||||
monologueResources.compile(glyphResourcePack);
|
||||
}
|
||||
|
||||
public void compile() {
|
||||
|
||||
@ -1,128 +0,0 @@
|
||||
package ru.dragonestia.msb3.api.talk;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.minestom.server.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.GlyphComponentBuilder;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.ImageGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.GlyphResourcePack;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.ResourceIdentifier;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.StringIdentifier;
|
||||
import ru.dragonestia.msb3.api.util.ResourceFromJar;
|
||||
import ru.dragonestia.msb3.api.util.StringUtil;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
public final class MonologueRenderer {
|
||||
|
||||
private static final Key MONOLOG_FONT_KEY = Key.key("msb3", "monolog");
|
||||
private static final Writable DEFAULT_COMPANION_AVATAR_WRITABLE = ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/monologue/default_avatar.png");
|
||||
private static final Writable COMPANION_AVATAR_FRAME_WRITABLE = ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/monologue/avatar_frame.png");
|
||||
private static final Writable SPEECH_INDICATOR_WRITABLE = ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/monologue/speech_indicator.png");
|
||||
private static final Component INDENT_COMPONENT = Component.text(" ".repeat(14));
|
||||
private static final ImageGlyph AVATAR_FRAME;
|
||||
private static final ImageGlyph DEFAULT_AVATAR;
|
||||
private static final ImageGlyph SPEECH_INDICATOR;
|
||||
private static final ResourceIdentifier<@NotNull ImageGlyph> AVATAR_FRAME_RESOURCE_IDENTIFIER;
|
||||
private static final ResourceIdentifier<@NotNull ImageGlyph> SPEECH_INDICATOR_RESOURCE_IDENTIFIER;
|
||||
private static final ResourceIdentifier<@NotNull ImageGlyph> DEFAULT_AVATAR_RESOURCE_IDENTIFIER;
|
||||
|
||||
static {
|
||||
AVATAR_FRAME = ImageGlyph.of(MONOLOG_FONT_KEY,
|
||||
Texture.texture().key(Key.key("msb3", "monolog/avatar_frame.png")).data(COMPANION_AVATAR_FRAME_WRITABLE).build(),
|
||||
new TextureProperties(50, 6));
|
||||
|
||||
DEFAULT_AVATAR = ImageGlyph.of(MONOLOG_FONT_KEY,
|
||||
Texture.texture().key(Key.key("msb3", "monolog/default_avatar.png")).data(DEFAULT_COMPANION_AVATAR_WRITABLE).build(),
|
||||
new TextureProperties(42, 2));
|
||||
|
||||
SPEECH_INDICATOR = ImageGlyph.of(MONOLOG_FONT_KEY,
|
||||
Texture.texture().key(Key.key("msb3", "monolog/speech_indicator.png")).data(SPEECH_INDICATOR_WRITABLE).build(),
|
||||
new TextureProperties(8, 6));
|
||||
|
||||
AVATAR_FRAME_RESOURCE_IDENTIFIER = StringIdentifier.image("monolog_avatar_frame");
|
||||
SPEECH_INDICATOR_RESOURCE_IDENTIFIER = StringIdentifier.image("monolog_speech_indicator");
|
||||
DEFAULT_AVATAR_RESOURCE_IDENTIFIER = StringIdentifier.image("monolog_default_avatar");
|
||||
}
|
||||
|
||||
private final Player player;
|
||||
private final String title;
|
||||
private final String message;
|
||||
|
||||
private MonologueRenderer(Player player, String title, String message) {
|
||||
this.player = player;
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
player.sendMessage(toComponent(ServerBootstrap.getInstance().getResourcePackManager().getGlyphResourcePack()));
|
||||
}
|
||||
|
||||
public static MonologueRenderer create(Player player, String title, String message) {
|
||||
return new MonologueRenderer(player, title, message);
|
||||
}
|
||||
|
||||
private Component toComponent(@NotNull GlyphResourcePack resourcePack) {
|
||||
Component text = Component.text(message);
|
||||
Component[] parts = StringUtil.splitIntoParts(text, 180, string -> string.length() * 4);
|
||||
if (parts != null && parts.length != 0) {
|
||||
int avatarLineStart = Math.max(parts.length - 4, 0) / 2;
|
||||
if (parts.length > 3) ++avatarLineStart;
|
||||
|
||||
var avatarComponent = GlyphComponentBuilder.universal(resourcePack.spaces())
|
||||
.append(resourcePack.get(AVATAR_FRAME_RESOURCE_IDENTIFIER))
|
||||
.append(4, resourcePack.get(DEFAULT_AVATAR_RESOURCE_IDENTIFIER))
|
||||
.build();
|
||||
|
||||
var titleComponent = Component.empty()
|
||||
.append(resourcePack.get(SPEECH_INDICATOR_RESOURCE_IDENTIFIER).toAdventure())
|
||||
.append(Component.space()).append(Component.text(title, NamedTextColor.WHITE, TextDecoration.BOLD));
|
||||
|
||||
var monolog = Component.text();
|
||||
|
||||
int lineIdx;
|
||||
for(lineIdx = 0; lineIdx < parts.length + 2; ++lineIdx) {
|
||||
if (lineIdx == avatarLineStart) {
|
||||
monolog.append(avatarComponent);
|
||||
}
|
||||
|
||||
monolog.append(INDENT_COMPONENT);
|
||||
if (lineIdx == 0) {
|
||||
monolog.append(Component.newline());
|
||||
}
|
||||
|
||||
if (lineIdx == 1) {
|
||||
monolog.append(titleComponent).append(Component.newline());
|
||||
}
|
||||
|
||||
if (lineIdx > 1) {
|
||||
monolog.append(parts[lineIdx - 2].applyFallbackStyle(Style.style(NamedTextColor.GRAY)))
|
||||
.append(Component.newline());
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.length < 4) {
|
||||
for(lineIdx = parts.length + 2; lineIdx < 5; ++lineIdx) {
|
||||
monolog.append(Component.newline());
|
||||
}
|
||||
}
|
||||
|
||||
return monolog.asComponent();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot fit speech text");
|
||||
}
|
||||
}
|
||||
|
||||
public static void compile(GlyphResourcePack resourcePack) {
|
||||
resourcePack.with(DEFAULT_AVATAR_RESOURCE_IDENTIFIER, DEFAULT_AVATAR)
|
||||
.with(SPEECH_INDICATOR_RESOURCE_IDENTIFIER, SPEECH_INDICATOR)
|
||||
.with(AVATAR_FRAME_RESOURCE_IDENTIFIER, AVATAR_FRAME);
|
||||
}
|
||||
}
|
||||
21
api/src/main/java/ru/dragonestia/msb3/api/talk/Themes.java
Normal file
21
api/src/main/java/ru/dragonestia/msb3/api/talk/Themes.java
Normal file
@ -0,0 +1,21 @@
|
||||
package ru.dragonestia.msb3.api.talk;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import ru.dragonestia.msb3.api.talk.monologue.MonologueTheme;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@UtilityClass
|
||||
public class Themes {
|
||||
|
||||
private final Map<String, MonologueTheme> monologueThemes = new HashMap<>();
|
||||
|
||||
public void registerMonologueTheme(String identifier, MonologueTheme theme) {
|
||||
monologueThemes.put(identifier, theme);
|
||||
}
|
||||
|
||||
public MonologueTheme getMonologueTheme(String identifier) {
|
||||
return monologueThemes.get(identifier);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package ru.dragonestia.msb3.api.talk.monologue;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.minestom.server.entity.Player;
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.GlyphComponentBuilder;
|
||||
import ru.dragonestia.msb3.api.util.StringUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class Monologue {
|
||||
|
||||
private static final Component INDENT_COMPONENT = Component.text(" ".repeat(14));
|
||||
|
||||
private final Player player;
|
||||
private final String title;
|
||||
private final String message;
|
||||
|
||||
private Monologue(Player player, String title, String message) {
|
||||
this.player = player;
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
show(MonologueTheme.builder().build());
|
||||
}
|
||||
|
||||
public void show(MonologueTheme theme) {
|
||||
player.sendMessage(toComponent(theme));
|
||||
}
|
||||
|
||||
public static Monologue create(Player player, String title, String message) {
|
||||
return new Monologue(player, title, message);
|
||||
}
|
||||
|
||||
private Component toComponent(MonologueTheme theme) {
|
||||
var spaces = ServerBootstrap.getInstance().getResourcePackManager().getGlyphResourcePack().spaces();
|
||||
var speech = ServerBootstrap.getInstance().getResourcePackManager().getMonologueResources().getSpeechIndicator();
|
||||
|
||||
Component text = Component.text(message);
|
||||
Component[] parts = StringUtil.splitIntoParts(text, 180, string -> string.length() * 4);
|
||||
if (parts != null && parts.length != 0) {
|
||||
int avatarLineStart = Math.max(parts.length - 4, 0) / 2;
|
||||
if (parts.length > 3) ++avatarLineStart;
|
||||
|
||||
var avatarComponent = GlyphComponentBuilder.universal(spaces)
|
||||
.append(Objects.requireNonNull(theme.getFrame()))
|
||||
.append(4, Objects.requireNonNull(theme.getAvatar()))
|
||||
.build();
|
||||
|
||||
var titleComponent = Component.empty()
|
||||
.append(speech.toAdventure())
|
||||
.append(Component.space()).append(Component.text(title, theme.getTitleColor(), TextDecoration.BOLD));
|
||||
|
||||
var monolog = Component.text();
|
||||
|
||||
int lineIdx;
|
||||
for(lineIdx = 0; lineIdx < parts.length + 2; ++lineIdx) {
|
||||
if (lineIdx == avatarLineStart) {
|
||||
monolog.append(avatarComponent);
|
||||
}
|
||||
|
||||
monolog.append(INDENT_COMPONENT);
|
||||
if (lineIdx == 0) {
|
||||
monolog.append(Component.newline());
|
||||
}
|
||||
|
||||
if (lineIdx == 1) {
|
||||
monolog.append(titleComponent).append(Component.newline());
|
||||
}
|
||||
|
||||
if (lineIdx > 1) {
|
||||
monolog.append(parts[lineIdx - 2].applyFallbackStyle(Style.style(theme.getTextColor())))
|
||||
.append(Component.newline());
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.length < 4) {
|
||||
for(lineIdx = parts.length + 2; lineIdx < 5; ++lineIdx) {
|
||||
monolog.append(Component.newline());
|
||||
}
|
||||
}
|
||||
|
||||
return monolog.asComponent();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot fit speech text");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
package ru.dragonestia.msb3.api.talk.monologue;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.ImageGlyph;
|
||||
import ru.dragonestia.msb3.api.resource.MonologueResources;
|
||||
import ru.dragonestia.msb3.api.resource.ResourcePackManager;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Log4j2
|
||||
@Getter
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class MonologueTheme {
|
||||
|
||||
private final ResourcePackManager resourcePackManager = ServerBootstrap.getInstance().getResourcePackManager();
|
||||
private final ImageGlyph avatar;
|
||||
private final ImageGlyph frame;
|
||||
private final TextColor titleColor;
|
||||
private final TextColor textColor;
|
||||
|
||||
public MonologueTheme withAvatar(String identifier) {
|
||||
var opt = resourcePackManager.getMonologueResources().getAvatar(identifier);
|
||||
if (opt.isPresent()) {
|
||||
return withAvatar(opt.get());
|
||||
}
|
||||
|
||||
log.warn("No avatar found for identifier '{}'. Using default", identifier);
|
||||
withAvatar(MonologueResources.DEFAULT);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MonologueTheme withAvatar(ImageGlyph avatar) {
|
||||
return new MonologueTheme(avatar, frame, titleColor, textColor);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final ResourcePackManager resourcePackManager;
|
||||
|
||||
private ImageGlyph avatar = null;
|
||||
private ImageGlyph frame = null;
|
||||
private TextColor titleColor = null;
|
||||
private TextColor textColor = null;
|
||||
|
||||
private Builder() {
|
||||
resourcePackManager = ServerBootstrap.getInstance().getResourcePackManager();
|
||||
}
|
||||
|
||||
public MonologueTheme build() {
|
||||
if (avatar == null) {
|
||||
setAvatar(MonologueResources.DEFAULT);
|
||||
if (avatar == null) {
|
||||
throw new IllegalStateException("Trying to get avatar before resource pack initialization");
|
||||
}
|
||||
}
|
||||
if (frame == null) {
|
||||
setFrame(MonologueResources.DEFAULT);
|
||||
if (frame == null) {
|
||||
throw new IllegalStateException("Trying to get frame before resource pack initialization");
|
||||
}
|
||||
}
|
||||
if (titleColor == null) setTitleColor(NamedTextColor.WHITE);
|
||||
if (textColor == null) setTextColor(NamedTextColor.GRAY);
|
||||
|
||||
return new MonologueTheme(
|
||||
avatar,
|
||||
frame,
|
||||
titleColor,
|
||||
textColor
|
||||
);
|
||||
}
|
||||
|
||||
public Builder setAvatar(ImageGlyph avatar) {
|
||||
this.avatar = avatar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setFrame(ImageGlyph frame) {
|
||||
this.frame = frame;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAvatar(String identifier) {
|
||||
var opt = resourcePackManager.getMonologueResources().getAvatar(identifier);
|
||||
if (opt.isPresent()) {
|
||||
avatar = Objects.requireNonNull(opt.get());
|
||||
return this;
|
||||
}
|
||||
|
||||
log.warn("No avatar found for identifier '{}'. Using default", identifier);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setFrame(String identifier) {
|
||||
var opt = resourcePackManager.getMonologueResources().getFrame(identifier);
|
||||
if (opt.isPresent()) {
|
||||
frame = Objects.requireNonNull(opt.get());
|
||||
return this;
|
||||
}
|
||||
|
||||
log.warn("No frame found for identifier '{}'. Using default", identifier);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTitleColor(TextColor titleColor) {
|
||||
this.titleColor = titleColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTextColor(TextColor textColor) {
|
||||
this.textColor = textColor;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package ru.dragonestia.msb3.api.util;
|
||||
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -8,6 +9,10 @@ import java.net.URLConnection;
|
||||
|
||||
public interface ResourceFromJar {
|
||||
|
||||
static Writable of(String fileName) {
|
||||
return of(ServerBootstrap.CLASS_LOADER, fileName);
|
||||
}
|
||||
|
||||
static Writable of(ClassLoader classLoader, String fileName) {
|
||||
return Writable.inputStream(() -> {
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user