From 5358741edb4939fbddc529c0410c57189a3dbb93 Mon Sep 17 00:00:00 2001 From: LambdAurora Date: Mon, 25 Nov 2024 19:35:10 +0100 Subject: [PATCH] Fix item frames (& similar) not ticking properly on the integrated server. --- CHANGELOG.md | 4 + README.md | 2 +- .../kotlin/lambdynamiclights/Constants.kt | 2 +- .../gui/RandomPrideFlagBackground.java | 83 ++++++++++++++++--- .../lightsource/BlockAttachedEntityMixin.java | 8 +- 5 files changed, 83 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b69be9fa..43012059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -212,6 +212,10 @@ - Fixed dynamic lighting of various projectiles. - Fixed water-sensitive items lighting up underwater while they shouldn't. +### 3.1.3 + +- Fixed item frames and other "block-attached" entities not ticking properly on the integrated server. + [SpruceUI]: https://github.com/LambdAurora/SpruceUI "SpruceUI page" [pridelib]: https://github.com/Queerbric/pridelib "Pridelib page" [Sodium]: https://modrinth.com/mod/sodium "Sodium Modrinth page" diff --git a/README.md b/README.md index 10aaaea2..21d3d613 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ GitHub -# 📖 Compatibility +## 📖 Compatibility - [Sodium] is recommended for better performances. - **OptiFabric is obviously incompatible.** diff --git a/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt b/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt index 96d7adaf..b46bcb6a 100644 --- a/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt +++ b/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt @@ -5,7 +5,7 @@ import org.gradle.accessors.dm.LibrariesForLibs object Constants { const val GROUP = "dev.lambdaurora" const val NAME = "lambdynamiclights" - const val VERSION = "3.1.2" + const val VERSION = "3.1.3" const val JAVA_VERSION = 21 private var minecraftVersion: String? = null diff --git a/src/main/java/dev/lambdaurora/lambdynlights/gui/RandomPrideFlagBackground.java b/src/main/java/dev/lambdaurora/lambdynlights/gui/RandomPrideFlagBackground.java index 48b99921..8c8d3190 100644 --- a/src/main/java/dev/lambdaurora/lambdynlights/gui/RandomPrideFlagBackground.java +++ b/src/main/java/dev/lambdaurora/lambdynlights/gui/RandomPrideFlagBackground.java @@ -16,10 +16,14 @@ import dev.lambdaurora.spruceui.util.ColorUtil; import dev.lambdaurora.spruceui.widget.SpruceWidget; import io.github.queerbric.pride.PrideFlag; +import io.github.queerbric.pride.PrideFlagShape; import io.github.queerbric.pride.PrideFlagShapes; import io.github.queerbric.pride.PrideFlags; +import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.Text; import net.minecraft.resources.Identifier; import org.joml.Matrix4f; import org.joml.Vector4f; @@ -32,48 +36,59 @@ * If you have an issue with this, I don't care. * * @author LambdAurora - * @version 2.1.0 + * @version 3.1.3 * @since 2.1.0 */ public class RandomPrideFlagBackground implements Background { private static final Background SECOND_LAYER = new SimpleColorBackground(0xe0101010); + private static final IntList DEFAULT_RAINBOW_COLORS = IntList.of( + 0xffff0018, 0xffffa52c, 0xffffff41, 0xff008018, 0xff0000f9, 0xff86007d + ); + private static final PrideFlagShape PROGRESS = PrideFlagShapes.get(Identifier.of("pride", "progress")); private static final Random RANDOM = new Random(); private final PrideFlag flag; + private final boolean nuhUh; - public RandomPrideFlagBackground(PrideFlag flag) { + RandomPrideFlagBackground(PrideFlag flag, boolean nuhUh) { this.flag = flag; + this.nuhUh = nuhUh; + } + + private IntList getColors() { + return this.nuhUh ? DEFAULT_RAINBOW_COLORS : this.flag.getColors(); } @Override public void render(GuiGraphics graphics, SpruceWidget widget, int vOffset, int mouseX, int mouseY, float delta) { int x = widget.getX(); int y = widget.getY(); + int width = widget.getWidth(); + int height = widget.getHeight(); RenderSystem.setShader(GameRenderer::getPositionColorShader); - if (this.flag.getShape() == PrideFlagShapes.get(Identifier.of("pride", "horizontal_stripes"))) { + if (this.nuhUh || this.flag.getShape() == PrideFlagShapes.get(Identifier.of("pride", "horizontal_stripes"))) { var model = graphics.matrixStack().peek().model(); var tessellator = Tessellator.getInstance(); var vertices = tessellator.begin(VertexFormat.Mode.TRIANGLES, DefaultVertexFormat.POSITION_COLOR); - int width = widget.getWidth(); - int height = widget.getHeight(); + var colors = this.getColors(); - float partHeight = height / (this.flag.getColors().size() - 1.f); + float partHeight = height / (colors.size() - 1.f); // First one float rightY = y; float leftY = y; - int[] color = ColorUtil.unpackARGBColor(this.flag.getColors().getInt(0)); + int[] color = ColorUtil.unpackARGBColor(colors.getInt(0)); vertex(vertices, model, x + width, rightY + partHeight, 0).color(color[0], color[1], color[2], color[3]); vertex(vertices, model, x + width, rightY, 0).color(color[0], color[1], color[2], color[3]); vertex(vertices, model, x, leftY, 0).color(color[0], color[1], color[2], color[3]); rightY += partHeight; - for (int i = 1; i < this.flag.getColors().size() - 1; i++) { - color = ColorUtil.unpackARGBColor(this.flag.getColors().getInt(i)); + for (int i = 1; i < colors.size() - 1; i++) { + color = ColorUtil.unpackARGBColor(colors.getInt(i)); vertex(vertices, model, x + width, rightY + partHeight, 0).color(color[0], color[1], color[2], color[3]); vertex(vertices, model, x + width, rightY, 0).color(color[0], color[1], color[2], color[3]); @@ -88,7 +103,7 @@ public void render(GuiGraphics graphics, SpruceWidget widget, int vOffset, int m } // Last one - color = ColorUtil.unpackARGBColor(this.flag.getColors().getInt(this.flag.getColors().size() - 1)); + color = ColorUtil.unpackARGBColor(colors.getInt(colors.size() - 1)); vertex(vertices, model, x + width, rightY, 0).color(color[0], color[1], color[2], color[3]); vertex(vertices, model, x, leftY, 0).color(color[0], color[1], color[2], color[3]); vertex(vertices, model, x, y + height, 0).color(color[0], color[1], color[2], color[3]); @@ -103,6 +118,19 @@ public void render(GuiGraphics graphics, SpruceWidget widget, int vOffset, int m } SECOND_LAYER.render(graphics, widget, vOffset, mouseX, mouseY, delta); + + if (this.nuhUh) { + var text = Text.literal("Nuh uh, you're not going to remove this, try harder :3c"); + var font = Minecraft.getInstance().font; + var lines = font.wrapLines(text, width - 8); + + int startY = y + height - 24 - lines.size() * (font.lineHeight + 2); + + for (var line : lines) { + graphics.drawCenteredShadowedText(font, line, x + width / 2, startY, 0xffff0000); + startY += font.lineHeight + 2; + } + } } /** @@ -111,7 +139,40 @@ public void render(GuiGraphics graphics, SpruceWidget widget, int vOffset, int m * @return the background */ public static Background random() { - return new RandomPrideFlagBackground(PrideFlags.getRandomFlag(RANDOM)); + var flag = PrideFlags.getRandomFlag(RANDOM); + boolean nuhUh = flag == null || (flag.getShape() != PROGRESS && areColorsSpoofed(flag.getColors())); + + return new RandomPrideFlagBackground(flag, nuhUh); + } + + private static boolean areColorsSpoofed(IntList colors) { + if (colors.size() < 2) { + return true; + } else { + int maxDist = 0; + + for (int colorA : colors) { + for (int colorB : colors) { + int dist = colorDist(colorA, colorB); + + if (dist > maxDist) { + maxDist = dist; + } + } + } + + return maxDist < 10; + } + } + + private static int colorDist(int a, int b) { + // https://en.wikipedia.org/wiki/Color_difference#sRGB + float r = (ColorUtil.argbUnpackRed(a) + ColorUtil.argbUnpackRed(b)) / 2.f; + int deltaR = ColorUtil.argbUnpackRed(a) - ColorUtil.argbUnpackRed(b); + int deltaG = ColorUtil.argbUnpackGreen(a) - ColorUtil.argbUnpackGreen(b); + int deltaB = ColorUtil.argbUnpackBlue(a) - ColorUtil.argbUnpackBlue(b); + + return (int) Math.sqrt((2 + r / 256.f) * deltaR * deltaR + 4 * deltaG * deltaG + (2 + (255 - r) / 256) * deltaB * deltaB); } private static VertexConsumer vertex(BufferBuilder builder, Matrix4f matrix, float x, float y, float z) { diff --git a/src/main/java/dev/lambdaurora/lambdynlights/mixin/lightsource/BlockAttachedEntityMixin.java b/src/main/java/dev/lambdaurora/lambdynlights/mixin/lightsource/BlockAttachedEntityMixin.java index 07f026ed..79297bda 100644 --- a/src/main/java/dev/lambdaurora/lambdynlights/mixin/lightsource/BlockAttachedEntityMixin.java +++ b/src/main/java/dev/lambdaurora/lambdynlights/mixin/lightsource/BlockAttachedEntityMixin.java @@ -17,6 +17,9 @@ import net.minecraft.world.entity.decoration.BlockAttachedEntity; import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(BlockAttachedEntity.class) public abstract class BlockAttachedEntityMixin extends Entity implements DynamicLightSource { @@ -24,9 +27,8 @@ public BlockAttachedEntityMixin(EntityType type, Level level) { super(type, level); } - @Override - public void tick() { - super.tick(); + @Inject(method = "tick", at = @At("RETURN")) + public void lambdynlights$onTick(CallbackInfo ci) { // We do not want to update the entity on the server. if (this.level().isClientSide()) { if (this.isRemoved()) {