mirror of
https://github.com/TeamMidnightDust/PictureSign.git
synced 2025-12-11 12:05:09 +01:00
PictureSign 2.0 Beta 1 - Video support & rotations
- Port to 1.20.1 - Add support for video playback using VLCj - YouTube videos are being played using Invidious, as VLC currently doesn't support YouTube playback - Add ability to rotate images (on X, Y & Z-axis; only with exceedVanillaLineLength enabled) - Marginally improve PictureSign helper screen - Way less bugs - GUI for Video & Rotation - Support for Hanging signs - Improved config screen - Ability to select shader program pictures are being rendered with when using Iris - Brightness of images is now based on light level at sign position by default - Ability to load URLs defined in JSON files, allowing for very long URLs like those of Twitch.tv streams, as well as start and stop times for videos
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.0-SNAPSHOT'
|
||||
id 'fabric-loom' version '1.2-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
@@ -17,12 +17,6 @@ repositories {
|
||||
maven {
|
||||
url = "https://api.modrinth.com/maven"
|
||||
}
|
||||
maven {
|
||||
url "https://cursemaven.com"
|
||||
content {
|
||||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
flatDir {
|
||||
dirs("localMaven")
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version=1.19
|
||||
yarn_mappings=1.19+build.4
|
||||
loader_version=0.14.8
|
||||
minecraft_version=1.20.1
|
||||
yarn_mappings=1.20.1+build.2
|
||||
loader_version=0.14.21
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.5.0
|
||||
mod_version = 2.0.0-beta.1
|
||||
maven_group = eu.midnightdust
|
||||
archives_base_name = picturesign
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.56.0+1.19
|
||||
midnightlib_version=1.0.0-fabric
|
||||
videolib_version=0.2.0-mnd
|
||||
fabric_version=0.83.1+1.20.1
|
||||
midnightlib_version=1.4.1-fabric
|
||||
videolib_version=0.2.1-mnd
|
||||
vlcj_version=4.8.2
|
||||
|
||||
iris_version=1.19.x-v1.2.5
|
||||
iris_version=1.6.4+1.20
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Binary file not shown.
@@ -38,20 +38,22 @@ public class PictureSignClient implements ClientModInitializer {
|
||||
ClientBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register((blockEntity, world) -> {
|
||||
if (PlatformFunctions.isModLoaded("videolib")) {
|
||||
BlockPos pos = blockEntity.getPos();
|
||||
Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ());
|
||||
Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+"_f");
|
||||
VideoHandler.closePlayer(videoId);
|
||||
Identifier videoId2 = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+"_b");
|
||||
VideoHandler.closePlayer(videoId2);
|
||||
}
|
||||
});
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
if (!PictureSignClient.BINDING_COPY_SIGN.isPressed()) return;
|
||||
PictureSignClient.BINDING_COPY_SIGN.setPressed(false);
|
||||
if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.BLOCK) return;
|
||||
if (client.crosshairTarget.getType() == HitResult.Type.BLOCK && client.world.getBlockState(new BlockPos(client.crosshairTarget.getPos())).hasBlockEntity()) {
|
||||
if (client.world.getBlockEntity(new BlockPos(client.crosshairTarget.getPos())) instanceof SignBlockEntity sign) {
|
||||
clipboard[0] = sign.getTextOnRow(0, false).getString();
|
||||
clipboard[1] = sign.getTextOnRow(1, false).getString();
|
||||
clipboard[2] = sign.getTextOnRow(2, false).getString();
|
||||
clipboard[3] = sign.getTextOnRow(3, false).getString();
|
||||
if (client.crosshairTarget.getType() == HitResult.Type.BLOCK && client.world.getBlockState(BlockPos.ofFloored(client.crosshairTarget.getPos())).hasBlockEntity()) {
|
||||
if (client.world.getBlockEntity(BlockPos.ofFloored(client.crosshairTarget.getPos())) instanceof SignBlockEntity sign) {
|
||||
boolean front = sign.isPlayerFacingFront(client.player);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
clipboard[i] = sign.getText(front).getMessage(i, false).getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,25 +2,45 @@ package eu.midnightdust.picturesign.config;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import eu.midnightdust.lib.config.MidnightConfig;
|
||||
import net.minecraft.client.gl.ShaderProgram;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class PictureSignConfig extends MidnightConfig {
|
||||
@Entry public static boolean enabled = true;
|
||||
@Entry public static boolean enableVideoSigns = true;
|
||||
@Entry public static boolean translucency = false;
|
||||
@Entry public static boolean helperUi = true;
|
||||
@Entry public static boolean exceedVanillaLineLength = true;
|
||||
@Entry public static boolean debug = false;
|
||||
@Entry(min = 1, max = 10) public static int maxThreads = 4;
|
||||
@Entry(min = 0, max = 4096) public static int signRenderDistance = 64;
|
||||
@Entry public static boolean safeMode = true;
|
||||
@Comment public static Comment ebeWarning;
|
||||
@Comment public static Comment ebeWarning2;
|
||||
@Entry public static List<String> safeProviders = Lists.newArrayList("https://i.imgur.com/", "https://i.ibb.co/", "https://pictshare.net/", "https://iili.io/");
|
||||
@Entry public static MissingImageMode missingImageMode = MissingImageMode.BLACK;
|
||||
public static final String general = "1general";
|
||||
private final static String advanced = "advanced";
|
||||
|
||||
@Entry(category = general) public static boolean enabled = true;
|
||||
@Entry(category = general) public static boolean enableVideoSigns = true;
|
||||
@Entry(category = general) public static boolean translucency = false;
|
||||
@Entry(category = general) public static boolean fullBrightPicture = false;
|
||||
@Entry(category = general) public static boolean helperUi = true;
|
||||
@Entry(category = general) public static boolean exceedVanillaLineLength = true;
|
||||
@Entry(category = advanced) public static boolean debug = false;
|
||||
@Entry(min = 1, max = 10, isSlider = true, category = advanced) public static int maxThreads = 4;
|
||||
@Entry(min = 0, max = 2048, isSlider = true, category = general) public static int signRenderDistance = 64;
|
||||
@Entry(category = general) public static boolean safeMode = true;
|
||||
@Entry(category = general) public static List<String> safeProviders = Lists.newArrayList("https://i.imgur.com/", "https://i.ibb.co/", "https://pictshare.net/", "https://iili.io/", "https://vimeo.com/", "https://yewtu.be/");
|
||||
@Entry(category = general) public static String invidiousInstance = "yt.oelrichsgarcia.de";
|
||||
@Comment(category = general) public static Comment ebeWarning;
|
||||
@Entry(category = advanced) public static MissingImageMode missingImageMode = MissingImageMode.BLACK;
|
||||
@Entry(category = advanced) public static PictureShader pictureShader = PictureShader.PosColTexLight;
|
||||
|
||||
public enum MissingImageMode {
|
||||
BLACK, MISSING_TEXTURE, TRANSPARENT
|
||||
}
|
||||
public enum PictureShader {
|
||||
PosColTexLight(GameRenderer::getPositionColorTexLightmapProgram),
|
||||
RenderTypeCutout(GameRenderer::getRenderTypeCutoutProgram),
|
||||
PosTex(GameRenderer::getPositionTexProgram),
|
||||
PosColTex(GameRenderer::getPositionColorTexProgram),
|
||||
PosTexCol(GameRenderer::getPositionTexColorProgram);
|
||||
|
||||
PictureShader(Supplier<ShaderProgram> program) {
|
||||
this.program = program;
|
||||
}
|
||||
public final Supplier<ShaderProgram> program;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package eu.midnightdust.picturesign.mixin;
|
||||
|
||||
import eu.midnightdust.picturesign.config.PictureSignConfig;
|
||||
import eu.midnightdust.picturesign.render.PictureSignRenderer;
|
||||
import eu.midnightdust.picturesign.util.PictureSignType;
|
||||
import net.minecraft.block.entity.SignBlockEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.block.entity.HangingSignBlockEntityRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(HangingSignBlockEntityRenderer.class)
|
||||
public abstract class MixinHangingSignBlockEntityRenderer implements BlockEntityRenderer<SignBlockEntity> {
|
||||
private static final MinecraftClient client = MinecraftClient.getInstance();
|
||||
PictureSignRenderer psRenderer = new PictureSignRenderer();
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "render")
|
||||
public void ps$onRender(SignBlockEntity sign, float f, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, CallbackInfo ci) {
|
||||
if (PictureSignConfig.enabled) {
|
||||
if (!PictureSignType.isType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, light, overlay, true);
|
||||
if (!PictureSignType.isType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, light, overlay, false);
|
||||
}
|
||||
}
|
||||
@Unique
|
||||
@Override
|
||||
public int getRenderDistance() {
|
||||
return PictureSignConfig.signRenderDistance;
|
||||
}
|
||||
@Unique
|
||||
@Override
|
||||
public boolean rendersOutsideBoundingBox(SignBlockEntity sign) {
|
||||
return PictureSignConfig.enabled && !PictureSignType.hasNoPicture(sign);
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,10 @@ public abstract class MixinSignBlockEntity extends BlockEntity {
|
||||
@Override
|
||||
@Unique
|
||||
public void markRemoved() {
|
||||
Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ());
|
||||
Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_f");
|
||||
Identifier videoId2 = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_b");
|
||||
VideoHandler.closePlayer(videoId);
|
||||
VideoHandler.closePlayer(videoId2);
|
||||
super.markRemoved();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import eu.midnightdust.picturesign.config.PictureSignConfig;
|
||||
import eu.midnightdust.picturesign.render.PictureSignRenderer;
|
||||
import eu.midnightdust.picturesign.util.PictureSignType;
|
||||
import net.minecraft.block.entity.SignBlockEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.block.entity.SignBlockEntityRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -17,17 +19,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(SignBlockEntityRenderer.class)
|
||||
public abstract class MixinSignBlockEntityRenderer implements BlockEntityRenderer<SignBlockEntity> {
|
||||
private static final MinecraftClient client = MinecraftClient.getInstance();
|
||||
PictureSignRenderer psRenderer = new PictureSignRenderer();
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "render")
|
||||
public void ps$onRender(SignBlockEntity sign, float f, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, CallbackInfo ci) {
|
||||
if (PictureSignConfig.enabled && !PictureSignType.isType(sign, PictureSignType.NONE)) {
|
||||
psRenderer.render(sign, matrixStack, light, overlay);
|
||||
if (PictureSignConfig.enabled) {
|
||||
if (!PictureSignType.isType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, light, overlay, true);
|
||||
if (!PictureSignType.isType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, light, overlay, false);
|
||||
}
|
||||
}
|
||||
@Inject(at = @At("HEAD"), method = "shouldRender", cancellable = true)
|
||||
private static void shouldRender(SignBlockEntity sign, int signColor, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (PictureSignConfig.enabled && !PictureSignType.isType(sign, PictureSignType.NONE)) cir.setReturnValue(true);
|
||||
private static void shouldRender(BlockPos pos, int signColor, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (PictureSignConfig.enabled && client.world != null && !PictureSignType.hasNoPicture((SignBlockEntity) client.world.getBlockEntity(pos))) cir.setReturnValue(true);
|
||||
}
|
||||
@Unique
|
||||
@Override
|
||||
@@ -37,6 +41,6 @@ public abstract class MixinSignBlockEntityRenderer implements BlockEntityRendere
|
||||
@Unique
|
||||
@Override
|
||||
public boolean rendersOutsideBoundingBox(SignBlockEntity sign) {
|
||||
return PictureSignConfig.enabled && !PictureSignType.isType(sign, PictureSignType.NONE);
|
||||
return PictureSignConfig.enabled && !PictureSignType.hasNoPicture(sign);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import eu.midnightdust.picturesign.config.PictureSignConfig;
|
||||
import eu.midnightdust.picturesign.screen.PictureSignHelperScreen;
|
||||
import net.minecraft.block.entity.SignBlockEntity;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.SignEditScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@@ -20,14 +20,17 @@ import java.util.Objects;
|
||||
|
||||
import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID;
|
||||
|
||||
@Mixin(SignEditScreen.class)
|
||||
@Mixin(AbstractSignEditScreen.class)
|
||||
public abstract class MixinSignEditScreen extends Screen {
|
||||
private static final Identifier PICTURESIGN_ICON_TEXTURE = new Identifier(MOD_ID,"textures/gui/picturesign_button.png");
|
||||
private static final Identifier CLIPBOARD_ICON_TEXTURE = new Identifier(MOD_ID,"textures/gui/clipboard_button.png");
|
||||
private static final Identifier TRASHBIN_ICON_TEXTURE = new Identifier(MOD_ID,"textures/gui/trashbin_button.png");
|
||||
@Shadow @Final private SignBlockEntity sign;
|
||||
@Shadow @Final private SignBlockEntity blockEntity;
|
||||
|
||||
@Shadow @Final private String[] text;
|
||||
@Shadow @Final private String[] messages;
|
||||
|
||||
@Shadow @Final private boolean front;
|
||||
private static boolean switchScreen = false;
|
||||
|
||||
protected MixinSignEditScreen(Text title) {
|
||||
super(title);
|
||||
@@ -38,21 +41,32 @@ public abstract class MixinSignEditScreen extends Screen {
|
||||
if (PictureSignClient.clipboard != null && PictureSignClient.clipboard[0] != null)
|
||||
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 84, this.height - 40, 20, 20, 0, 0, 20, CLIPBOARD_ICON_TEXTURE, 32, 64, (buttonWidget) -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
text[i] = PictureSignClient.clipboard[i];
|
||||
sign.setTextOnRow(i, Text.of(text[i]));
|
||||
messages[i] = PictureSignClient.clipboard[i];
|
||||
int finalI = i;
|
||||
blockEntity.changeText(changer -> changer.withMessage(finalI, Text.of(messages[finalI])), front);
|
||||
}
|
||||
}, Text.empty()));
|
||||
if (PictureSignConfig.helperUi)
|
||||
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 62, this.height - 40, 20, 20, 0, 0, 20, TRASHBIN_ICON_TEXTURE, 32, 64, (buttonWidget) -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
text[i] = "";
|
||||
sign.setTextOnRow(i, Text.empty());
|
||||
messages[i] = "";
|
||||
int finalI = i;
|
||||
blockEntity.changeText(changer -> changer.withMessage(finalI, Text.empty()), front);
|
||||
}
|
||||
}, Text.empty()));
|
||||
if (PictureSignConfig.helperUi)
|
||||
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 40, this.height - 40, 20, 20, 0, 0, 20, PICTURESIGN_ICON_TEXTURE, 32, 64, (buttonWidget) -> {
|
||||
sign.setEditable(true);
|
||||
Objects.requireNonNull(client).setScreen(new PictureSignHelperScreen(this.sign,false));
|
||||
switchScreen = true;
|
||||
Objects.requireNonNull(client).setScreen(new PictureSignHelperScreen(this.blockEntity, front, false));
|
||||
}, Text.empty()));
|
||||
}
|
||||
@Inject(at = @At("HEAD"), method = "removed", cancellable = true)
|
||||
private void picturesign$removed(CallbackInfo ci) {
|
||||
if (switchScreen) {
|
||||
switchScreen = false;
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.world.World;
|
||||
import org.joml.*;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
@@ -25,9 +26,9 @@ import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID;
|
||||
|
||||
public class PictureSignRenderer {
|
||||
private boolean isSafeUrl;
|
||||
|
||||
public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, int light, int overlay) {
|
||||
String url = PictureURLUtils.getLink(signBlockEntity);
|
||||
private boolean hasRotation = false;
|
||||
public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, int light, int overlay, boolean front) {
|
||||
String url = PictureURLUtils.getLink(signBlockEntity, front);
|
||||
PictureInfo info = null;
|
||||
if (!url.contains("://")) {
|
||||
url = "https://" + url;
|
||||
@@ -40,19 +41,25 @@ public class PictureSignRenderer {
|
||||
if (!url.contains("://")) {
|
||||
url = "https://" + url;
|
||||
}
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE) && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg")) return;
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front) && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg")) return;
|
||||
if (PictureSignConfig.safeMode) {
|
||||
isSafeUrl = false;
|
||||
String finalUrl = url;
|
||||
PictureSignConfig.safeProviders.forEach(safe -> {
|
||||
if (!isSafeUrl) isSafeUrl = finalUrl.startsWith(safe);
|
||||
});
|
||||
if (!isSafeUrl) return;
|
||||
if (!isSafeUrl && !url.startsWith("https://youtu.be/") && !url.startsWith("https://youtube.com/") && !url.startsWith("https://www.youtube.com/")) return;
|
||||
}
|
||||
if ((!PictureSignConfig.enableVideoSigns || !PlatformFunctions.isModLoaded("videolib")) && !PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front)) return;
|
||||
if (url.startsWith("https://youtube.com/") || url.startsWith("https://www.youtube.com/watch?v=") || url.startsWith("https://youtu.be/")) {
|
||||
url = url.replace("https://www.", "https://");
|
||||
url = url.replace("youtube.com/watch?v=", PictureSignConfig.invidiousInstance.replace("https://", "").replace("/", "")+"/latest_version?id=");
|
||||
url = url.replace("youtu.be/", PictureSignConfig.invidiousInstance.replace("https://", "").replace("/", "")+"/latest_version?id=");
|
||||
}
|
||||
if ((!PictureSignConfig.enableVideoSigns || !PlatformFunctions.isModLoaded("videolib")) && !PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE)) return;
|
||||
World world = signBlockEntity.getWorld();
|
||||
BlockPos pos = signBlockEntity.getPos();
|
||||
Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ());
|
||||
String videoSuffix = front ? "_f" : "_b";
|
||||
Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+videoSuffix);
|
||||
if (world != null && ((world.getBlockState(pos.down()).getBlock().equals(Blocks.REDSTONE_TORCH) || world.getBlockState(pos.down()).getBlock().equals(Blocks.REDSTONE_WALL_TORCH))
|
||||
&& world.getBlockState(pos.down()).get(Properties.LIT).equals(false)
|
||||
|| (world.getBlockState(pos.up()).getBlock().equals(Blocks.REDSTONE_TORCH) || world.getBlockState(pos.up()).getBlock().equals(Blocks.REDSTONE_WALL_TORCH))
|
||||
@@ -63,7 +70,7 @@ public class PictureSignRenderer {
|
||||
return;
|
||||
}
|
||||
|
||||
String lastLine = signBlockEntity.getTextOnRow(3, false).getString();
|
||||
String lastLine = signBlockEntity.getText(front).getMessage(3, false).getString();
|
||||
|
||||
if (!lastLine.matches("(.*\\d:.*\\d:.*\\d:.*\\d:.*\\d)")) return;
|
||||
|
||||
@@ -82,16 +89,32 @@ public class PictureSignRenderer {
|
||||
}
|
||||
catch (NumberFormatException ignored) {}
|
||||
|
||||
String thirdLine = signBlockEntity.getText(front).getMessage(2, false).getString();
|
||||
hasRotation = thirdLine.matches("(.*\\d:.*\\d:.*\\d)");
|
||||
float xRot = 0;
|
||||
float yRot = 0;
|
||||
float zRot = 0;
|
||||
|
||||
if (hasRotation) {
|
||||
String[] rotation = thirdLine.split(":");
|
||||
try {
|
||||
xRot = Float.parseFloat(rotation[0]);
|
||||
yRot = Float.parseFloat(rotation[1]);
|
||||
zRot = Float.parseFloat(rotation[2]);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// Download the picture data
|
||||
PictureDownloader.PictureData data = null;
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE)) {
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front)) {
|
||||
data = PictureDownloader.getInstance().getPicture(url);
|
||||
if (data == null || data.identifier == null) return;
|
||||
}
|
||||
else if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO) || PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO)) {
|
||||
else if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO, front) || PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO, front)) {
|
||||
VideoHandler.videoPlayers.add(videoId);
|
||||
try {
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO) && !VideoHandler.hasMedia(videoId)) {
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO, front) && !VideoHandler.hasMedia(videoId)) {
|
||||
VideoHandler.play(videoId, url);
|
||||
VideoHandler.setRepeat(videoId, true);
|
||||
}
|
||||
@@ -108,12 +131,12 @@ public class PictureSignRenderer {
|
||||
}
|
||||
else return;
|
||||
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO)) VideoHandler.playedOnce.add(videoId);
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO, front)) VideoHandler.playedOnce.add(videoId);
|
||||
|
||||
float xOffset = 0.0F;
|
||||
float zOffset = 0.0F;
|
||||
|
||||
Quaternion yRotation = Vec3f.POSITIVE_Y.getDegreesQuaternion(0F);
|
||||
float yRotation = 0;
|
||||
|
||||
if (signBlockEntity.getCachedState().contains(Properties.HORIZONTAL_FACING)) {
|
||||
Direction direction = signBlockEntity.getCachedState().get(Properties.HORIZONTAL_FACING);
|
||||
@@ -121,48 +144,48 @@ public class PictureSignRenderer {
|
||||
case NORTH -> {
|
||||
zOffset = 1.01F;
|
||||
xOffset = 1.0F;
|
||||
yRotation = Vec3f.POSITIVE_Y.getDegreesQuaternion(180.0F);
|
||||
yRotation = 180;
|
||||
}
|
||||
case SOUTH -> zOffset = 0.010F;
|
||||
case EAST -> {
|
||||
zOffset = 1.01F;
|
||||
yRotation = Vec3f.POSITIVE_Y.getDegreesQuaternion(90.0F);
|
||||
yRotation = 90;
|
||||
}
|
||||
case WEST -> {
|
||||
yRotation = Vec3f.POSITIVE_Y.getDegreesQuaternion(-90.0F);
|
||||
yRotation = -90;
|
||||
xOffset = 1.01F;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (signBlockEntity.getCachedState().contains(Properties.ROTATION)) {
|
||||
yRotation = Vec3f.POSITIVE_Y.getDegreesQuaternion(signBlockEntity.getCachedState().get(Properties.ROTATION) * -22.5f);
|
||||
yRotation = signBlockEntity.getCachedState().get(Properties.ROTATION) * -22.5f;
|
||||
}
|
||||
else return;
|
||||
if (!front) yRotation -= 180f;
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder buffer = tessellator.getBuffer();
|
||||
|
||||
int l;
|
||||
int l = PictureSignConfig.fullBrightPicture ? 15728880 : light;
|
||||
if (FabricLoader.getInstance().isModLoaded("iris") && IrisApi.getInstance().isShaderPackInUse()) {
|
||||
RenderSystem.setShader(GameRenderer::getRenderTypeCutoutShader);
|
||||
l = 15728880;
|
||||
}
|
||||
else {
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorTexLightmapShader);
|
||||
l = light;
|
||||
RenderSystem.setShader(PictureSignConfig.pictureShader.program);
|
||||
}
|
||||
else RenderSystem.setShader(GameRenderer::getPositionColorTexLightmapProgram);
|
||||
|
||||
Identifier texture;
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE)) {
|
||||
if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front)) {
|
||||
assert data != null;
|
||||
texture = data.identifier;
|
||||
}
|
||||
else if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO) || PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO))
|
||||
else if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO, front) || PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO, front))
|
||||
texture = VideoHandler.getTexture(videoId);
|
||||
else return;
|
||||
TextureManager textureManager = MinecraftClient.getInstance().getTextureManager();
|
||||
if (textureManager.getTexture(texture) == null || (textureManager.getTexture(texture) instanceof NativeImageBackedTexture nativeTexture && nativeTexture.getImage() == null)) {
|
||||
if (textureManager.getTexture(texture) == null || (textureManager.getTexture(texture) instanceof NativeImageBackedTexture nativeTexture && nativeTexture.getImage() == null) ||
|
||||
(!PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front) && VideoHandler.getFramerate(videoId) < 1)) {
|
||||
if (PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.TRANSPARENT)) return;
|
||||
texture = PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.BLACK) ? (new Identifier(MOD_ID, "textures/black.png")) : (TextureManager.MISSING_IDENTIFIER);
|
||||
texture = PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.BLACK) ?
|
||||
(new Identifier(MOD_ID, "textures/black.png")) : (TextureManager.MISSING_IDENTIFIER);
|
||||
}
|
||||
RenderSystem.setShaderTexture(0, texture);
|
||||
|
||||
@@ -173,7 +196,12 @@ public class PictureSignRenderer {
|
||||
|
||||
matrixStack.push();
|
||||
matrixStack.translate(xOffset + x, y, zOffset + z);
|
||||
matrixStack.multiply(yRotation);
|
||||
matrixStack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yRotation + yRot));
|
||||
matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(xRot));
|
||||
matrixStack.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(zRot));
|
||||
//System.out.println(hasRotation +" "+ xRot + " " + yRot + " " + zRot);
|
||||
|
||||
//matrixStack.multiply(new Quaternionf(new AxisAngle4d(Math.toRadians(yRotation + yRot), 0, 1, 0)));
|
||||
|
||||
Matrix4f matrix4f = matrixStack.peek().getPositionMatrix();
|
||||
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT);
|
||||
|
||||
@@ -3,13 +3,17 @@ package eu.midnightdust.picturesign.screen;
|
||||
import eu.midnightdust.lib.util.screen.TexturedOverlayButtonWidget;
|
||||
import eu.midnightdust.picturesign.PictureSignClient;
|
||||
import eu.midnightdust.picturesign.config.PictureSignConfig;
|
||||
import eu.midnightdust.picturesign.util.PictureSignType;
|
||||
import eu.midnightdust.picturesign.util.PictureURLUtils;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SignBlock;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.entity.SignBlockEntity;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.HangingSignEditScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.SignEditScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.render.*;
|
||||
@@ -18,11 +22,15 @@ import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket;
|
||||
import net.minecraft.screen.ScreenTexts;
|
||||
import net.minecraft.text.OrderedText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID;
|
||||
@@ -33,34 +41,43 @@ public class PictureSignHelperScreen extends Screen {
|
||||
private static final Identifier TRASHBIN_ICON_TEXTURE = new Identifier(MOD_ID,"textures/gui/trashbin_button.png");
|
||||
private final SignBlockEntity sign;
|
||||
private SignBlockEntityRenderer.SignModel model;
|
||||
private String[] text;
|
||||
protected String[] text;
|
||||
private final boolean front;
|
||||
private final boolean isHanging;
|
||||
protected final WoodType signType;
|
||||
private static boolean switchScreen = false;
|
||||
private PictureSignType pictureSignType = PictureSignType.PICTURE;
|
||||
|
||||
public PictureSignHelperScreen(SignBlockEntity sign, boolean filtered) {
|
||||
super(Text.translatable("sign.edit"));
|
||||
public PictureSignHelperScreen(SignBlockEntity sign, boolean front, boolean filtered) {
|
||||
super((sign.getCachedState().getBlock() instanceof HangingSignBlock || sign.getCachedState().getBlock() instanceof WallHangingSignBlock) ? Text.translatable("hanging_sign.edit") : Text.translatable("sign.edit"));
|
||||
this.text = IntStream.range(0, 4).mapToObj((row) ->
|
||||
sign.getTextOnRow(row, filtered)).map(Text::getString).toArray(String[]::new);
|
||||
sign.getText(front).getMessage(row, filtered)).map(Text::getString).toArray(String[]::new);
|
||||
this.sign = sign;
|
||||
this.signType = AbstractSignBlock.getWoodType(sign.getCachedState().getBlock());
|
||||
this.isHanging = sign.getCachedState().getBlock() instanceof HangingSignBlock || sign.getCachedState().getBlock() instanceof WallHangingSignBlock;
|
||||
|
||||
this.front = front;
|
||||
}
|
||||
protected void init() {
|
||||
super.init();
|
||||
if (this.client == null) return;
|
||||
sign.setEditable(false);
|
||||
text = IntStream.range(0, 4).mapToObj((row) ->
|
||||
sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new);
|
||||
sign.getText(front).getMessage(row, false)).map(Text::getString).toArray(String[]::new);
|
||||
if (!text[3].matches("(.*\\d:.*\\d:.*\\d:.*\\d:.*\\d)")) text[3] = "1:1:0:0:0";
|
||||
if (!text[0].startsWith("!PS:") && !text[0].startsWith("!VS:") && !text[0].startsWith("!LS:")) text[0] = "!PS:"+text[0];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
sign.setTextOnRow(i, Text.of(text[i]));
|
||||
if (text[2].isBlank() && PictureSignConfig.exceedVanillaLineLength) text[2] = "0:0:0";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int finalI = i;
|
||||
sign.changeText(changer -> changer.withMessage(finalI, Text.of(text[finalI])), front);
|
||||
}
|
||||
this.addDrawableChild(new ButtonWidget(this.width / 2 - 100, this.height / 4 + 120, 200, 20, ScreenTexts.DONE, (button) -> {
|
||||
this.finishEditing();
|
||||
}));
|
||||
this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> this.finishEditing()).dimensions(this.width / 2 - 100, this.height / 4 + 120, 200, 20).build());
|
||||
|
||||
if (PictureSignClient.clipboard != null && PictureSignClient.clipboard[0] != null)
|
||||
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 84, this.height - 40, 20, 20, 0, 0, 20, CLIPBOARD_ICON_TEXTURE, 32, 64, (buttonWidget) -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
text[i] = PictureSignClient.clipboard[i];
|
||||
sign.setTextOnRow(i, Text.of(text[i]));
|
||||
int finalI = i;
|
||||
sign.changeText(changer -> changer.withMessage(finalI, Text.of(text[finalI])), front);
|
||||
}
|
||||
assert client != null;
|
||||
client.setScreen(this);
|
||||
@@ -69,178 +86,172 @@ public class PictureSignHelperScreen extends Screen {
|
||||
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 62, this.height - 40, 20, 20, 0, 0, 20, TRASHBIN_ICON_TEXTURE, 32, 64, (buttonWidget) -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
text[i] = "";
|
||||
sign.setTextOnRow(i, Text.empty());
|
||||
int finalI = i;
|
||||
sign.changeText(changer -> changer.withMessage(finalI, Text.empty()), front);
|
||||
}
|
||||
assert client != null;
|
||||
client.setScreen(this);
|
||||
}, Text.of("")));
|
||||
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 40, this.height - 40, 20, 20, 0, 0, 20, TEXTSIGN_ICON_TEXTURE, 32, 64, (buttonWidget) -> {
|
||||
sign.setEditable(true);
|
||||
Objects.requireNonNull(client).setScreen(new SignEditScreen(this.sign,false));
|
||||
switchScreen = true;
|
||||
Objects.requireNonNull(client).setScreen(isHanging ? new HangingSignEditScreen(this.sign, false, front) : new SignEditScreen(this.sign, front, false));
|
||||
}, Text.of("")));
|
||||
this.addDrawableChild(new ButtonWidget(this.width / 2,this.height / 5 + 70,40,20, Text.of(text[0].startsWith("!PS:") ? "Image" : (text[0].startsWith("!VS:") ? "Video" : "Loop")), (buttonWidget) -> {
|
||||
if (text[0].startsWith("!VS:")) pictureSignType = PictureSignType.VIDEO;
|
||||
if (text[0].startsWith("!LS:")) pictureSignType = PictureSignType.LOOPED_VIDEO;
|
||||
this.addDrawableChild(ButtonWidget.builder(Text.of(text[0].startsWith("!PS:") ? "Image" : (text[0].startsWith("!VS:") ? "Video" : "Loop")), (buttonWidget) -> {
|
||||
if (text[0].startsWith("!PS:")) text[0] = "!VS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", "");
|
||||
else if (text[0].startsWith("!VS:")) text[0] = "!LS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", "");
|
||||
else if (text[0].startsWith("!LS:")) text[0] = "!PS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", "");
|
||||
else text[0] = "!PS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", "");
|
||||
buttonWidget.setMessage(Text.of(text[0].startsWith("!PS:") ? "Image" : (text[0].startsWith("!VS:") ? "Video" : "Loop")));
|
||||
pictureSignType = text[0].startsWith("!PS:") ? PictureSignType.PICTURE : (text[0].startsWith("!VS:") ? PictureSignType.VIDEO : PictureSignType.LOOPED_VIDEO);
|
||||
|
||||
sign.setTextOnRow(0, Text.of(text[0]));
|
||||
}));
|
||||
sign.changeText(changer -> changer.withMessage(0, Text.of(text[0])), front);
|
||||
}).dimensions(this.width / 2,this.height / 5 + 70,40,20).build());
|
||||
TextFieldWidget linkWidget = new TextFieldWidget(textRenderer,this.width / 2 - 175,this.height / 5 + 13,215,40, Text.of("url"));
|
||||
linkWidget.setMaxLength(900);
|
||||
linkWidget.setText(PictureURLUtils.getLink(sign));
|
||||
linkWidget.setText(PictureURLUtils.getLink(sign, front));
|
||||
linkWidget.setChangedListener(s -> {
|
||||
String prefix = "";
|
||||
if (text[0].startsWith("!PS:")) prefix = "!PS:";
|
||||
else if (text[0].startsWith("!VS:")) prefix = "!VS:";
|
||||
else if (text[0].startsWith("!LS:")) prefix = "!LS:";
|
||||
String[] lines = breakLink(prefix, PictureURLUtils.shortenLink(s));
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int i = 0; i < (PictureSignConfig.exceedVanillaLineLength ? 2 : 3); i++) {
|
||||
text[i] = lines[i];
|
||||
sign.setTextOnRow(i, Text.of(text[i]));
|
||||
int finalI = i;
|
||||
sign.changeText(changer -> changer.withMessage(finalI, Text.of(text[finalI])), front);
|
||||
}
|
||||
});
|
||||
this.addDrawableChild(linkWidget);
|
||||
String[] initialDimensions = text[3].split(":");
|
||||
TextFieldWidget widthWidget = new TextFieldWidget(textRenderer,this.width / 2 - 175,this.height / 5 + 70,30,20, Text.of("width"));
|
||||
widthWidget.setText(initialDimensions[0]);
|
||||
widthWidget.setChangedListener(s -> {
|
||||
String[] dimensions = new String[5];
|
||||
for (int i = 0; i < dimensions.length; ++i){
|
||||
if (text[3].split(":").length > i)
|
||||
dimensions[i] = text[3].split(":")[i];
|
||||
}
|
||||
dimensions[0] = s;
|
||||
StringBuilder mergedDimensions = new StringBuilder();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (dimensions[i] == null) dimensions[i] = "";
|
||||
mergedDimensions.append(dimensions[i]);
|
||||
if (i < 4)mergedDimensions.append(":");
|
||||
}
|
||||
text[3] = String.valueOf(mergedDimensions);
|
||||
sign.setTextOnRow(3, Text.of(text[3]));
|
||||
});
|
||||
this.addDrawableChild(widthWidget);
|
||||
TextFieldWidget heightWidget = new TextFieldWidget(textRenderer,this.width / 2 - 140,this.height / 5 + 70,30,20, Text.of("height"));
|
||||
heightWidget.setText(initialDimensions[1]);
|
||||
heightWidget.setChangedListener(s -> {
|
||||
String[] dimensions = new String[5];
|
||||
for (int i = 0; i < dimensions.length; ++i){
|
||||
if (text[3].split(":").length > i)
|
||||
dimensions[i] = text[3].split(":")[i];
|
||||
}
|
||||
dimensions[1] = s;
|
||||
StringBuilder mergedDimensions = new StringBuilder();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (dimensions[i] == null) dimensions[i] = "";
|
||||
mergedDimensions.append(dimensions[i]);
|
||||
if (i < 4)mergedDimensions.append(":");
|
||||
}
|
||||
text[3] = String.valueOf(mergedDimensions);
|
||||
sign.setTextOnRow(3, Text.of(text[3]));
|
||||
});
|
||||
this.addDrawableChild(heightWidget);
|
||||
TextFieldWidget posXWidget = new TextFieldWidget(textRenderer,this.width / 2 - 105,this.height / 5 + 70,30,20, Text.of("posX"));
|
||||
posXWidget.setText(initialDimensions[2]);
|
||||
posXWidget.setChangedListener(s -> {
|
||||
String[] dimensions = new String[5];
|
||||
for (int i = 0; i < dimensions.length; ++i){
|
||||
if (text[3].split(":").length > i)
|
||||
dimensions[i] = text[3].split(":")[i];
|
||||
}
|
||||
dimensions[2] = s;
|
||||
StringBuilder mergedDimensions = new StringBuilder();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (dimensions[i] == null) dimensions[i] = "";
|
||||
mergedDimensions.append(dimensions[i]);
|
||||
if (i < 4)mergedDimensions.append(":");
|
||||
}
|
||||
text[3] = String.valueOf(mergedDimensions);
|
||||
sign.setTextOnRow(3, Text.of(text[3]));
|
||||
});
|
||||
this.addDrawableChild(posXWidget);
|
||||
TextFieldWidget posYWidget = new TextFieldWidget(textRenderer,this.width / 2 - 70,this.height / 5 + 70,30,20, Text.of("posY"));
|
||||
posYWidget.setText(initialDimensions[3]);
|
||||
posYWidget.setChangedListener(s -> {
|
||||
String[] dimensions = new String[5];
|
||||
for (int i = 0; i < dimensions.length; ++i){
|
||||
if (text[3].split(":").length > i)
|
||||
dimensions[i] = text[3].split(":")[i];
|
||||
}
|
||||
dimensions[3] = s;
|
||||
StringBuilder mergedDimensions = new StringBuilder();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (dimensions[i] == null) dimensions[i] = "";
|
||||
mergedDimensions.append(dimensions[i]);
|
||||
if (i < 4)mergedDimensions.append(":");
|
||||
}
|
||||
text[3] = String.valueOf(mergedDimensions);
|
||||
sign.setTextOnRow(3, Text.of(text[3]));
|
||||
});
|
||||
this.addDrawableChild(posYWidget);
|
||||
TextFieldWidget posZWidget = new TextFieldWidget(textRenderer,this.width / 2 - 35,this.height / 5 + 70,30,20, Text.of("posZ"));
|
||||
widthWidget.setText(initialDimensions[0]);
|
||||
heightWidget.setText(initialDimensions[1]);
|
||||
posXWidget.setText(initialDimensions[2]);
|
||||
posYWidget.setText(initialDimensions[3]);
|
||||
posZWidget.setText(initialDimensions[4]);
|
||||
posZWidget.setChangedListener(s -> {
|
||||
String[] dimensions = new String[5];
|
||||
for (int i = 0; i < dimensions.length; ++i){
|
||||
if (text[3].split(":").length > i)
|
||||
dimensions[i] = text[3].split(":")[i];
|
||||
}
|
||||
dimensions[4] = s;
|
||||
StringBuilder mergedDimensions = new StringBuilder();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (dimensions[i] == null) dimensions[i] = "";
|
||||
mergedDimensions.append(dimensions[i]);
|
||||
if (i < 4)mergedDimensions.append(":");
|
||||
}
|
||||
text[3] = String.valueOf(mergedDimensions);
|
||||
sign.setTextOnRow(3, Text.of(text[3]));
|
||||
});
|
||||
widthWidget.setChangedListener(s -> applyPosition(s, 0));
|
||||
heightWidget.setChangedListener(s -> applyPosition(s, 1));
|
||||
posXWidget.setChangedListener(s -> applyPosition(s, 2));
|
||||
posYWidget.setChangedListener(s -> applyPosition(s, 3));
|
||||
posZWidget.setChangedListener(s -> applyPosition(s, 4));
|
||||
this.addDrawableChild(widthWidget);
|
||||
this.addDrawableChild(heightWidget);
|
||||
this.addDrawableChild(posXWidget);
|
||||
this.addDrawableChild(posYWidget);
|
||||
this.addDrawableChild(posZWidget);
|
||||
this.model = SignBlockEntityRenderer.createSignModel(this.client.getEntityModelLoader(), SignBlockEntityRenderer.getSignType(sign.getCachedState().getBlock()));
|
||||
if (text[2].matches("(.*\\d:.*\\d:.*\\d)")) addRotationWidgets();
|
||||
this.model = SignBlockEntityRenderer.createSignModel(this.client.getEntityModelLoader(), AbstractSignBlock.getWoodType(sign.getCachedState().getBlock()));
|
||||
}
|
||||
public void applyPosition(String position, int index) {
|
||||
String[] dimensions = new String[5];
|
||||
for (int i = 0; i < dimensions.length; ++i){
|
||||
if (text[3].split(":").length > i)
|
||||
dimensions[i] = text[3].split(":")[i];
|
||||
}
|
||||
dimensions[index] = position;
|
||||
StringBuilder mergedDimensions = new StringBuilder();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (dimensions[i] == null) dimensions[i] = "";
|
||||
mergedDimensions.append(dimensions[i]);
|
||||
if (i < 4)mergedDimensions.append(":");
|
||||
}
|
||||
text[3] = String.valueOf(mergedDimensions);
|
||||
sign.changeText(changer -> changer.withMessage(3, Text.of(text[3])), front);
|
||||
}
|
||||
public void addRotationWidgets() {
|
||||
String[] initialRotation = text[2].split(":");
|
||||
RotationSliderWidget rotXWidget = new RotationSliderWidget(this.width / 2 - 176,this.height / 5 + 100,70,20, Integer.parseInt(initialRotation[0]));
|
||||
RotationSliderWidget rotYWidget = new RotationSliderWidget(this.width / 2 - 103,this.height / 5 + 100,70,20, Integer.parseInt(initialRotation[1]));
|
||||
RotationSliderWidget rotZWidget = new RotationSliderWidget(this.width / 2 - 30,this.height / 5 + 100,70,20, Integer.parseInt(initialRotation[2]));
|
||||
rotXWidget.setChangedListener(s -> applyRotation(s, 0));
|
||||
rotYWidget.setChangedListener(s -> applyRotation(s, 1));
|
||||
rotZWidget.setChangedListener(s -> applyRotation(s, 2));
|
||||
this.addDrawableChild(rotXWidget);
|
||||
this.addDrawableChild(rotYWidget);
|
||||
this.addDrawableChild(rotZWidget);
|
||||
}
|
||||
public void applyRotation(int rotation, int index) {
|
||||
String[] dimensions = new String[3];
|
||||
for (int i = 0; i < dimensions.length; ++i){
|
||||
if (text[2].split(":").length > i)
|
||||
dimensions[i] = text[2].split(":")[i];
|
||||
}
|
||||
dimensions[index] = String.valueOf(rotation);
|
||||
StringBuilder mergedDimensions = new StringBuilder();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (dimensions[i] == null) dimensions[i] = "";
|
||||
mergedDimensions.append(dimensions[i]);
|
||||
if (i < 2)mergedDimensions.append(":");
|
||||
}
|
||||
text[2] = String.valueOf(mergedDimensions);
|
||||
sign.changeText(changer -> changer.withMessage(2, Text.of(text[2])), front);
|
||||
}
|
||||
public static class RotationSliderWidget extends SliderWidget {
|
||||
private Consumer<Integer> changedListener;
|
||||
|
||||
public RotationSliderWidget(int x, int y, int width, int height, int rot) {
|
||||
super(x, y, width, height, Text.of(String.valueOf(rot)), rot / (360d));
|
||||
}
|
||||
|
||||
protected void updateMessage() {
|
||||
this.setMessage(Text.of(String.valueOf(getValue())));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyValue() {
|
||||
changedListener.accept(getValue());
|
||||
}
|
||||
|
||||
protected int getValue() {
|
||||
return Double.valueOf(this.value * (360)).intValue();
|
||||
}
|
||||
public void setChangedListener(Consumer<Integer> changedListener) {
|
||||
this.changedListener = changedListener;
|
||||
}
|
||||
}
|
||||
public void removed() {
|
||||
if (this.client == null) return;
|
||||
if (this.client == null || switchScreen) return;
|
||||
ClientPlayNetworkHandler clientPlayNetworkHandler = this.client.getNetworkHandler();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sign.setTextOnRow(i, Text.of(text[i]));
|
||||
int finalI = i;
|
||||
sign.changeText(changer -> changer.withMessage(finalI, Text.of(text[finalI])), front);
|
||||
}
|
||||
if (clientPlayNetworkHandler != null) {
|
||||
clientPlayNetworkHandler.sendPacket(new UpdateSignC2SPacket(this.sign.getPos(), this.text[0], this.text[1], this.text[2], this.text[3]));
|
||||
clientPlayNetworkHandler.sendPacket(new UpdateSignC2SPacket(this.sign.getPos(), front, this.text[0], this.text[1], this.text[2], this.text[3]));
|
||||
}
|
||||
}
|
||||
|
||||
private String[] breakLink(String prefix, String link) {
|
||||
Text linkText = Text.of(prefix+link);
|
||||
String[] brokenLink = new String[3];
|
||||
Text line0Text = linkText;
|
||||
int line0width = line0Text.getString().length();
|
||||
assert this.client != null;
|
||||
while (this.client.textRenderer.getWidth(line0Text) >= 90) {
|
||||
--line0width;
|
||||
line0Text = Text.of(line0Text.getString().substring(0,line0width));
|
||||
assert client != null;
|
||||
List<OrderedText> text = client.textRenderer.wrapLines(linkText, 90);
|
||||
for (int i = 0; i < text.size(); i++) {
|
||||
String textLine = orderedToString(text.get(i));
|
||||
if (i < (PictureSignConfig.exceedVanillaLineLength ? 2 : 3))
|
||||
brokenLink[i] = textLine;
|
||||
else if (PictureSignConfig.exceedVanillaLineLength) brokenLink[1] += textLine;
|
||||
}
|
||||
brokenLink[0] = line0Text.getString();
|
||||
Text line1Text = Text.of(linkText.getString().substring(line0width));
|
||||
int line1width = line1Text.getString().length();
|
||||
assert this.client != null;
|
||||
while (this.client.textRenderer.getWidth(line1Text) >= 90) {
|
||||
--line1width;
|
||||
line1Text = Text.of(line1Text.getString().substring(0,line1width));
|
||||
}
|
||||
brokenLink[1] = line1Text.getString();
|
||||
Text line2Text = Text.of(linkText.getString().substring(line0width + line1width));
|
||||
int line2width = line2Text.getString().length();
|
||||
assert this.client != null;
|
||||
if (!PictureSignConfig.exceedVanillaLineLength)
|
||||
while (this.client.textRenderer.getWidth(line2Text) >= 90) {
|
||||
--line2width;
|
||||
line2Text = Text.of(line2Text.getString().substring(0,line2width));
|
||||
}
|
||||
brokenLink[2] = line2Text.getString();
|
||||
|
||||
return brokenLink;
|
||||
}
|
||||
private String orderedToString(OrderedText ordered) {
|
||||
StringBuilder string = new StringBuilder();
|
||||
ordered.accept((i, style, codePoint) -> {
|
||||
string.append(Character.toString(codePoint));
|
||||
return true;
|
||||
}); return string.toString();
|
||||
}
|
||||
@Override
|
||||
public boolean shouldPause() {
|
||||
return false;
|
||||
}
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!this.sign.getType().supports(this.sign.getCachedState())) {
|
||||
@@ -252,40 +263,40 @@ public class PictureSignHelperScreen extends Screen {
|
||||
assert this.client != null;
|
||||
this.client.setScreen(null);
|
||||
}
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
if (this.client == null) return;
|
||||
DiffuseLighting.disableGuiDepthLighting();
|
||||
this.renderBackground(matrices);
|
||||
drawTextWithShadow(matrices,textRenderer, Text.of("Link" + (PictureSignConfig.safeMode ? " (imgur.com/imgbb.com/iili.io/pictshare.net)" : "")),this.width / 2 - 175, this.height / 5 + 3, -8816268);
|
||||
drawTextWithShadow(matrices,textRenderer, Text.of("Width"),this.width / 2 - 175, this.height / 5 + 60, -8816268);
|
||||
drawTextWithShadow(matrices,textRenderer, Text.of("Height"),this.width / 2 - 140, this.height / 5 + 60, -8816268);
|
||||
drawTextWithShadow(matrices,textRenderer, Text.of("PosX"),this.width / 2 - 105, this.height / 5 + 60, -8816268);
|
||||
drawTextWithShadow(matrices,textRenderer, Text.of("PosY"),this.width / 2 - 70, this.height / 5 + 60, -8816268);
|
||||
drawTextWithShadow(matrices,textRenderer, Text.of("PosZ"),this.width / 2 - 35, this.height / 5 + 60, -8816268);
|
||||
drawTextWithShadow(matrices,textRenderer, Text.of("Mode"),this.width / 2, this.height / 5 + 60, -8816268);
|
||||
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 40, 16777215);
|
||||
matrices.push();
|
||||
matrices.translate(this.width / 2f + 100, this.height / 5f - 60, 50.0);
|
||||
matrices.scale(93.75F, -93.75F, 93.75F);
|
||||
matrices.translate(0.0, -1.3125, 0.0);
|
||||
BlockState blockState = this.sign.getCachedState();
|
||||
boolean bl = blockState.getBlock() instanceof SignBlock;
|
||||
if (!bl) {
|
||||
matrices.translate(0.0, -0.3125, 0.0);
|
||||
this.renderBackground(context);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("Link" +
|
||||
(PictureSignConfig.safeMode ? (pictureSignType.equals(PictureSignType.PICTURE) ? " (imgur.com/imgbb.com/iili.io/pictshare.net)" : " (youtube.com/youtu.be/vimeo.com)") : "")),
|
||||
this.width / 2 - 175, this.height / 5 + 3, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("Width"),this.width / 2 - 175, this.height / 5 + 60, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("Height"),this.width / 2 - 140, this.height / 5 + 60, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("PosX"),this.width / 2 - 105, this.height / 5 + 60, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("PosY"),this.width / 2 - 70, this.height / 5 + 60, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("PosZ"),this.width / 2 - 35, this.height / 5 + 60, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("Mode"),this.width / 2, this.height / 5 + 60, -8816268);
|
||||
if (text[2].matches("(.*\\d:.*\\d:.*\\d)")) {
|
||||
context.drawTextWithShadow(textRenderer, Text.of("RotX"),this.width / 2 - 175, this.height / 5 + 92, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("RotY"),this.width / 2 - 103, this.height / 5 + 92, -8816268);
|
||||
context.drawTextWithShadow(textRenderer, Text.of("RotZ"),this.width / 2 - 30, this.height / 5 + 92, -8816268);
|
||||
}
|
||||
context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 40, 16777215);
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
matrices.push();
|
||||
matrices.scale(0.6666667F, -0.6666667F, -0.6666667F);
|
||||
VertexConsumerProvider.Immediate immediate = this.client.getBufferBuilders().getEntityVertexConsumers();
|
||||
SpriteIdentifier spriteIdentifier = TexturedRenderLayers.getSignTextureId(SignBlockEntityRenderer.getSignType(sign.getCachedState().getBlock()));
|
||||
SignBlockEntityRenderer.SignModel var10002 = this.model;
|
||||
Objects.requireNonNull(var10002);
|
||||
VertexConsumer vertexConsumer = spriteIdentifier.getVertexConsumer(immediate, var10002::getLayer);
|
||||
this.model.stick.visible = bl;
|
||||
this.model.root.render(matrices, vertexConsumer, 15728880, OverlayTexture.DEFAULT_UV);
|
||||
translateForRender(context, sign.getCachedState());
|
||||
renderSignBackground(context, sign.getCachedState());
|
||||
|
||||
int i = this.sign.getText(front).getColor().getSignColor();
|
||||
matrices.pop();
|
||||
matrices.translate(0.0, 0.3333333432674408, 0.046666666865348816);
|
||||
matrices.scale(0.010416667F, -0.010416667F, 0.010416667F);
|
||||
int i = this.sign.getTextColor().getSignColor();
|
||||
matrices.push();
|
||||
|
||||
context.getMatrices().translate((float)this.width / 2.0F + 100, this.height / 5f + 47.5f, 400.0F);
|
||||
if (sign.getCachedState().getBlock() instanceof SignBlock) context.getMatrices().translate(0,-15f,0);
|
||||
else if (isHanging) context.getMatrices().translate(0,17f,0);
|
||||
Vector3f vector3f = this.getTextScale();
|
||||
context.getMatrices().scale(vector3f.x(), vector3f.y(), vector3f.z());
|
||||
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
|
||||
|
||||
int m;
|
||||
@@ -298,7 +309,7 @@ public class PictureSignHelperScreen extends Screen {
|
||||
}
|
||||
|
||||
float n = (float)(-this.client.textRenderer.getWidth(string) / 2);
|
||||
this.client.textRenderer.draw(string, n, (float)(m * 10 - this.text.length * 5), i, false, matrix4f, immediate, false, 0, 15728880, false);
|
||||
this.client.textRenderer.draw(string, n, (float)(m * 10 - this.text.length * 5), i, false, matrix4f, immediate, TextRenderer.TextLayerType.NORMAL, 0, 15728880, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,6 +317,53 @@ public class PictureSignHelperScreen extends Screen {
|
||||
|
||||
matrices.pop();
|
||||
DiffuseLighting.enableGuiDepthLighting();
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
|
||||
super.render(context, mouseX, mouseY, delta);
|
||||
}
|
||||
protected void translateForRender(DrawContext context, BlockState state) {
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
if (isHanging) {
|
||||
matrices.translate((float)this.width / 2.0F + 100, this.height / 5f + 50, 50.0F);
|
||||
}
|
||||
else {
|
||||
matrices.push();
|
||||
matrices.translate(this.width / 2f + 100, this.height / 5f - 60, 50.0);
|
||||
matrices.scale(93.75F, -93.75F, 93.75F);
|
||||
matrices.translate(0.0, -1.3125, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderSignBackground(DrawContext context, BlockState state) {
|
||||
if (!isHanging) {
|
||||
VertexConsumerProvider.Immediate immediate = this.client.getBufferBuilders().getEntityVertexConsumers();
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
|
||||
BlockState blockState = this.sign.getCachedState();
|
||||
boolean bl = blockState.getBlock() instanceof SignBlock;
|
||||
if (!bl) {
|
||||
matrices.translate(0.0, -0.15625, 0.0);
|
||||
}
|
||||
matrices.push();
|
||||
matrices.scale(0.6666667F, -0.6666667F, -0.6666667F);
|
||||
|
||||
SpriteIdentifier spriteIdentifier = TexturedRenderLayers.getSignTextureId(AbstractSignBlock.getWoodType(sign.getCachedState().getBlock()));
|
||||
SignBlockEntityRenderer.SignModel var10002 = this.model;
|
||||
Objects.requireNonNull(var10002);
|
||||
VertexConsumer vertexConsumer = spriteIdentifier.getVertexConsumer(immediate, var10002::getLayer);
|
||||
this.model.stick.visible = bl;
|
||||
this.model.root.render(matrices, vertexConsumer, 15728880, OverlayTexture.DEFAULT_UV);
|
||||
matrices.pop();
|
||||
matrices.translate(0.0, 0.3333333432674408, 0.046666666865348816);
|
||||
matrices.scale(0.010416667F, -0.010416667F, 0.010416667F);
|
||||
}
|
||||
else {
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
matrices.scale(4.5F, 4.5F, 1.0F);
|
||||
context.drawTexture(new Identifier("textures/gui/hanging_signs/" + this.signType.name() + ".png"), -8, -8, 0.0F, 0.0F, 16, 16, 16, 16);
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector3f getTextScale() {
|
||||
return isHanging ? new Vector3f(1.0F, 1.0F, 1.0F) : new Vector3f(0.9765628F, 0.9765628F, 0.9765628F);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,17 @@ import net.minecraft.block.entity.SignBlockEntity;
|
||||
|
||||
public enum PictureSignType {
|
||||
NONE, PICTURE, VIDEO, LOOPED_VIDEO;
|
||||
public static PictureSignType getType(SignBlockEntity signBlockEntity) {
|
||||
String rowOne = signBlockEntity.getTextOnRow(0,false).getString();
|
||||
public static PictureSignType getType(SignBlockEntity signBlockEntity, boolean front) {
|
||||
String rowOne = signBlockEntity.getText(front).getMessage(0,false).getString();
|
||||
if (rowOne.startsWith("!PS:")) return PICTURE;
|
||||
if (rowOne.startsWith("!VS:")) return VIDEO;
|
||||
if (rowOne.startsWith("!LS:")) return LOOPED_VIDEO;
|
||||
else return NONE;
|
||||
}
|
||||
public static boolean isType(SignBlockEntity signBlockEntity, PictureSignType type) {
|
||||
return getType(signBlockEntity) == type;
|
||||
public static boolean isType(SignBlockEntity signBlockEntity, PictureSignType type, boolean front) {
|
||||
return getType(signBlockEntity, front) == type;
|
||||
}
|
||||
public static boolean hasNoPicture(SignBlockEntity signBlockEntity) {
|
||||
return isType(signBlockEntity, NONE, true) && isType(signBlockEntity, NONE, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class PictureURLUtils {
|
||||
public static final Type STRING_TYPE = new TypeToken<Map<String, String>>(){}.getType();
|
||||
public static final Map<String, PictureInfo> cachedJsonData = new HashMap<>();
|
||||
@@ -60,15 +59,16 @@ public class PictureURLUtils {
|
||||
catch (MalformedURLException e) {PictureSignClient.LOGGER.warn("Malformed URL: " + e);}
|
||||
return result;
|
||||
}
|
||||
public static String getLink(SignBlockEntity signBlockEntity) {
|
||||
String text = signBlockEntity.getTextOnRow(0, false).getString() +
|
||||
signBlockEntity.getTextOnRow(1, false).getString() +
|
||||
signBlockEntity.getTextOnRow(2, false).getString();
|
||||
public static String getLink(SignBlockEntity signBlockEntity, boolean front) {
|
||||
String text = signBlockEntity.getText(front).getMessage(0, false).getString() +
|
||||
signBlockEntity.getText(front).getMessage(1, false).getString();
|
||||
if (!signBlockEntity.getText(front).getMessage(2, false).getString().matches("(.*\\d:.*\\d:.*\\d)")) text += signBlockEntity.getText(front).getMessage(2, false).getString();
|
||||
String url = text.replaceAll("!PS:", "").replaceAll("!VS:", "").replaceAll("!LS:", "").replaceAll(" ","");
|
||||
if (url.startsWith("ps:")) url = url.replace("ps:", "https://pictshare.net/");
|
||||
if (url.startsWith("imgur:")) url = url.replace("imgur:", "https://i.imgur.com/");
|
||||
if (url.startsWith("imgbb:")) url = url.replace("imgbb:", "https://i.ibb.co/");
|
||||
if (url.startsWith("iili:")) url = url.replace("iili:", "https://iili.io/");
|
||||
if (url.startsWith("yt:")) url = url.replace("yt:", "https://youtu.be/");
|
||||
return url;
|
||||
}
|
||||
public static String shortenLink(String url) {
|
||||
@@ -76,9 +76,13 @@ public class PictureURLUtils {
|
||||
if (url.contains("i.imgur.com/")) url = url.replace("i.imgur.com/", "imgur:");
|
||||
if (url.contains("i.ibb.co/:")) url = url.replace("i.ibb.co/", "imgbb:");
|
||||
if (url.contains("iili.io/")) url = url.replace("iili.io/", "iili:");
|
||||
if (url.contains("www.youtube.com/")) url = url.replace("www.youtube.com/", "yt:");
|
||||
if (url.contains("youtu.be/")) url = url.replace("youtu.be/", "yt:");
|
||||
if (url.startsWith("https://")) {
|
||||
url = url.replace("https://", "");
|
||||
}
|
||||
if (url.contains("watch?v=")) url = url.replace("watch?v=", "");
|
||||
if (url.contains("&pp=")) url = url.split("&pp=")[0];
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,4 +38,7 @@ public class VideoHandler {
|
||||
public static Identifier getTexture(Identifier id) {
|
||||
return videoManager.getOrCreate(id).getTexture();
|
||||
}
|
||||
public static float getFramerate(Identifier id) {
|
||||
return videoManager.getOrCreate(id).getCodecInterface().getFrameRate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,22 @@
|
||||
"picturesign.midnightconfig.signRenderDistance":"Schildsichtweite",
|
||||
"picturesign.midnightconfig.safeMode":"Sicherer Modus",
|
||||
"picturesign.midnightconfig.safeMode.tooltip":"Lädt nur Bilder von vertrauten Seiten",
|
||||
"picturesign.midnightconfig.ebeWarning":"§cWenn du die Mod 'Enhanced Block Entities' benutzt, stelle sicher,",
|
||||
"picturesign.midnightconfig.ebeWarning2":"§cdass du alles in Relation zu Schildern in der EBE Config deaktiviert hast!",
|
||||
"picturesign.midnightconfig.ebeWarning":"§cWenn du die Mod 'Enhanced Block Entities' benutzt, stelle sicher, dass du alles in Relation zu Schildern in der EBE Config deaktiviert hast!",
|
||||
"picturesign.midnightconfig.safeProviders":"Sichere Anbieter",
|
||||
"picturesign.midnightconfig.missingImageMode":"Darstellung fehlender Texturen",
|
||||
"picturesign.midnightconfig.enum.MissingImageMode.BLACK":"Schwarz",
|
||||
"picturesign.midnightconfig.enum.MissingImageMode.MISSING_TEXTURE":"Schwarz & Lila",
|
||||
"picturesign.midnightconfig.enum.MissingImageMode.TRANSPARENT":"Transparent",
|
||||
"key.picturesign.copy_sign": "Text eines Schildes kopieren",
|
||||
"key.picturesign.edit_sign":"Schild bearbeiten"
|
||||
"key.picturesign.edit_sign":"Schild bearbeiten",
|
||||
|
||||
"picturesign.midnightconfig.category.1general": "Generell",
|
||||
"picturesign.midnightconfig.category.advanced": "Fortgeschritten",
|
||||
"picturesign.midnightconfig.enableVideoSigns": "Aktiviere Videos",
|
||||
"picturesign.midnightconfig.fullBrightPicture": "Höchste Helligkeit",
|
||||
"picturesign.midnightconfig.fullBrightPicture.tooltip": "Sorgt dafür, dass Bilder immer vollkommen beleuchtet dargestellt werden",
|
||||
"picturesign.midnightconfig.invidiousInstance": "Invidious-Instanz",
|
||||
"picturesign.midnightconfig.invidiousInstance.tooltip": "Wähle die Invidious-Instanz aus, die zur Wiedergabe von YouTube-Videos verwendet wird. \nEine Liste dieser ist zu finden unter\ndocs.invidious.io/instances/",
|
||||
"picturesign.midnightconfig.pictureShader": "Render-Programm",
|
||||
"picturesign.midnightconfig.pictureShader.tooltip": "Wähle das Shader-Programm, mit dem die Bilder dargestellt werden, was nützlich ist, wenn diese mit Shaderpacks nicht richtig dargestellt werden"
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
{
|
||||
"picturesign.midnightconfig.title":"PictureSign Config",
|
||||
"picturesign.midnightconfig.category.1general":"General",
|
||||
"picturesign.midnightconfig.category.advanced":"Advanced",
|
||||
|
||||
"picturesign.midnightconfig.enabled":"Enable Pictures",
|
||||
"picturesign.midnightconfig.enableVideoSigns":"Enable Videos",
|
||||
"picturesign.midnightconfig.translucency":"Enable Translucency",
|
||||
"picturesign.midnightconfig.translucency.tooltip":"Translucency doesn't work too great on block entities\n(and therefore signs)",
|
||||
"picturesign.midnightconfig.fullBrightPicture":"Full-bright Pictures",
|
||||
"picturesign.midnightconfig.fullBrightPicture.tooltip":"Makes pictures always appear fully lit",
|
||||
"picturesign.midnightconfig.helperUi":"Enable Helper UI",
|
||||
"picturesign.midnightconfig.exceedVanillaLineLength":"Exceed vanilla line length",
|
||||
"picturesign.midnightconfig.debug":"Debug mode",
|
||||
@@ -12,13 +16,21 @@
|
||||
"picturesign.midnightconfig.signRenderDistance":"Sign render distance",
|
||||
"picturesign.midnightconfig.safeMode":"Safe mode",
|
||||
"picturesign.midnightconfig.safeMode.tooltip":"Only load images from trusted providers",
|
||||
"picturesign.midnightconfig.ebeWarning":"§cIf you are using the mod 'Enhanced Block Entities'",
|
||||
"picturesign.midnightconfig.ebeWarning2":"§cmake sure to disable anything sign-related in it's config!",
|
||||
"picturesign.midnightconfig.ebeWarning":"§cIf you are using the mod 'Enhanced Block Entities' make sure to disable anything sign-related in it's config!",
|
||||
"picturesign.midnightconfig.safeProviders":"Safe providers",
|
||||
"picturesign.midnightconfig.invidiousInstance":"Invidious Instance",
|
||||
"picturesign.midnightconfig.invidiousInstance.tooltip":"Select the Invidious instance that is being used to play YouTube videos. \nYou can find a list of them at\ndocs.invidious.io/instances/",
|
||||
"picturesign.midnightconfig.missingImageMode":"Missing image mode",
|
||||
"picturesign.midnightconfig.enum.MissingImageMode.BLACK":"Black",
|
||||
"picturesign.midnightconfig.enum.MissingImageMode.MISSING_TEXTURE":"Black & Purple",
|
||||
"picturesign.midnightconfig.enum.MissingImageMode.TRANSPARENT":"Transparent",
|
||||
"picturesign.midnightconfig.pictureShader":"Render Program",
|
||||
"picturesign.midnightconfig.pictureShader.tooltip":"Select the shader program to draw pictures with when using shaderpacks where they appear black/buggy",
|
||||
"picturesign.midnightconfig.enum.PictureShader.PosColTexLight":"PosColTexLight",
|
||||
"picturesign.midnightconfig.enum.PictureShader.RenderTypeCutout":"RenderTypeCutout",
|
||||
"picturesign.midnightconfig.enum.PictureShader.PosTex":"PosTex",
|
||||
"picturesign.midnightconfig.enum.PictureShader.PosColTex":"PosColTex",
|
||||
"picturesign.midnightconfig.enum.PictureShader.PosTexCol":"PosTexCol",
|
||||
"key.picturesign.copy_sign":"Copy Text from Sign",
|
||||
"key.picturesign.edit_sign":"Edit Sign",
|
||||
"key.categories.picturesign":"PictureSign"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"client": [
|
||||
"MixinSignBlockEntityRenderer",
|
||||
"MixinHangingSignBlockEntityRenderer",
|
||||
"MixinSignEditScreen",
|
||||
"MixinSignBlockEntity"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user