Bump to 1.20.5

This commit is contained in:
Linnea Gräf
2024-04-26 18:04:45 +02:00
parent 041da7c7d1
commit 7e01515694
44 changed files with 351 additions and 358 deletions

2
.gitignore vendored
View File

@@ -2,6 +2,8 @@
# #
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
.env
.properties
/.gradle /.gradle
/build/ /build/
/buildSrc/.gradle /buildSrc/.gradle

View File

@@ -15,8 +15,8 @@ plugins {
kotlin("jvm") version "1.9.23" kotlin("jvm") version "1.9.23"
kotlin("plugin.serialization") version "1.9.23" kotlin("plugin.serialization") version "1.9.23"
// id("com.bnorm.power.kotlin-power-assert") version "0.13.0" // id("com.bnorm.power.kotlin-power-assert") version "0.13.0"
id("dev.architectury.loom") version "1.5.389" id("dev.architectury.loom") version "1.6.394"
id("com.github.johnrengelman.shadow") version "7.1.2" id("com.github.johnrengelman.shadow") version "8.1.1"
id("moe.nea.licenseextractificator") id("moe.nea.licenseextractificator")
// id("io.github.juuxel.loom-vineflower") version "1.11.0" // id("io.github.juuxel.loom-vineflower") version "1.11.0"
id("io.shcm.shsupercm.fabric.fletchingtable") version "1.5" id("io.shcm.shsupercm.fabric.fletchingtable") version "1.5"
@@ -25,17 +25,17 @@ plugins {
java { java {
withSourcesJar() withSourcesJar()
toolchain { toolchain {
languageVersion.set(JavaLanguageVersion.of(17)) languageVersion.set(JavaLanguageVersion.of(21))
} }
} }
val compileKotlin: KotlinCompile by tasks val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions { compileKotlin.kotlinOptions {
jvmTarget = "17" jvmTarget = "21"
} }
val compileTestKotlin: KotlinCompile by tasks val compileTestKotlin: KotlinCompile by tasks
compileTestKotlin.kotlinOptions { compileTestKotlin.kotlinOptions {
jvmTarget = "17" jvmTarget = "21"
} }
repositories { repositories {
@@ -47,11 +47,6 @@ repositories {
includeGroup("maven.modrinth") includeGroup("maven.modrinth")
} }
} }
maven("https://jitpack.io/") {
content {
includeGroupByRegex("(com|io)\\.github\\..+")
}
}
maven("https://repo.sleeping.town") { maven("https://repo.sleeping.town") {
content { content {
includeGroup("com.unascribed") includeGroup("com.unascribed")
@@ -71,6 +66,13 @@ repositories {
maven("https://server.bbkr.space/artifactory/libs-release") maven("https://server.bbkr.space/artifactory/libs-release")
maven("https://repo.nea.moe/releases") maven("https://repo.nea.moe/releases")
maven("https://maven.notenoughupdates.org/releases") maven("https://maven.notenoughupdates.org/releases")
maven("https://repo.nea.moe/mirror")
maven("https://jitpack.io/") {
content {
includeGroupByRegex("(com|io)\\.github\\..+")
excludeModule("io.github.cottonmc", "LibGui")
}
}
} }
kotlin { kotlin {
@@ -132,7 +134,8 @@ dependencies {
nonModImplentation(libs.nealisp) nonModImplentation(libs.nealisp)
shadowMe(libs.nealisp) shadowMe(libs.nealisp)
modApi(libs.fabric.api) modCompileOnly(libs.fabric.api)
modRuntimeOnly(libs.fabric.api.deprecated)
modApi(libs.architectury) modApi(libs.architectury)
modCompileOnly(libs.jarvis.api) modCompileOnly(libs.jarvis.api)
include(libs.jarvis.fabric) include(libs.jarvis.fabric)
@@ -187,6 +190,12 @@ loom {
property("firmament.debug", "true") property("firmament.debug", "true")
property("mixin.debug", "true") property("mixin.debug", "true")
parseEnvFile(file(".env")).forEach { (t, u) ->
environmentVariable(t, u)
}
parseEnvFile(file(".properties")).forEach{ (t, u) ->
property(t,u)
}
vmArg("-ea") vmArg("-ea")
vmArg("-XX:+AllowEnhancedClassRedefinition") vmArg("-XX:+AllowEnhancedClassRedefinition")
vmArg("-XX:HotswapAgent=external") vmArg("-XX:HotswapAgent=external")
@@ -197,7 +206,7 @@ loom {
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
options.encoding = "UTF-8" options.encoding = "UTF-8"
options.release.set(17) options.release.set(21)
} }
tasks.jar { tasks.jar {

18
buildSrc/src/EnvFile.kt Normal file
View File

@@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import java.io.File
fun parseEnvFile(file: File): Map<String, String> {
if (!file.exists()) return mapOf()
val map = mutableMapOf<String, String>()
for (line in file.readText().lines()) {
if (line.isEmpty() || line.startsWith("#")) continue
val parts = line.split("=", limit = 2)
map[parts[0]] = parts.getOrNull(1) ?: ""
}
return map
}

View File

@@ -3,37 +3,40 @@
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
[versions] [versions]
minecraft = "1.20.4" minecraft = "1.20.5"
fabric_loader = "0.15.6" fabric_loader = "0.15.10"
fabric_api = "0.95.0+1.20.4" fabric_api = "0.97.6+1.20.5"
fabric_kotlin = "1.10.19+kotlin.1.9.23" fabric_kotlin = "1.10.19+kotlin.1.9.23"
yarn = "1.20.4+build.3" yarn = "1.20.5+build.1"
libgui = "9.2.2+1.20.2" libgui = "9.2.4+1.20.5"
rei = "14.0.688" rei = "14.0.690-alpha"
devauth = "1.2.0" modmenu = "10.0.0-beta.1"
modmenu = "9.0.0" architectury = "12.0.26"
ktor = "2.3.0"
dbus_java = "4.2.1"
architectury = "11.0.11"
neurepoparser = "1.4.0"
qolify = "1.3.0-1.20.2" qolify = "1.3.0-1.20.2"
citresewn = "1.1.3+1.20" citresewn = "1.1.3+1.20"
hotswap_agent = "1.4.2-SNAPSHOT" sodium = "mc1.20.5-0.5.8"
sodium = "mc1.20.3-0.5.5" freecammod = "1.2.4+1.20.5"
freecammod = "1.2.0-mc1.20"
ncr = "Fabric-1.20.4-v2.5.0" ncr = "Fabric-1.20.4-v2.5.0"
explosiveenhancement = "1.2.2-1.20.x"
notenoughanimations = "9wrknT51"
devauth = "1.2.0"
ktor = "2.3.0"
dbus_java = "4.2.1"
neurepoparser = "1.4.0"
hotswap_agent = "1.4.2-SNAPSHOT"
mixinextras = "0.3.5" mixinextras = "0.3.5"
jarvis = "1.1.1" jarvis = "1.1.1"
nealisp = "1.0.0" nealisp = "1.0.0"
explosiveenhancement = "1.2.2-1.20.x"
moulconfig = "3.0.0-beta.5" moulconfig = "3.0.0-beta.5"
manninghamMills = "2.4.1" manninghamMills = "2.4.1"
notenoughanimations = "ZLjUeuU8"
[libraries] [libraries]
minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" }
fabric_loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric_loader" } fabric_loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric_loader" }
fabric_api = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "fabric_api" } fabric_api = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "fabric_api" }
fabric_api_deprecated = { module = "net.fabricmc.fabric-api:fabric-api-deprecated", version.ref = "fabric_api" }
fabric_kotlin = { module = "net.fabricmc:fabric-language-kotlin", version.ref = "fabric_kotlin" } fabric_kotlin = { module = "net.fabricmc:fabric-language-kotlin", version.ref = "fabric_kotlin" }
architectury = { module = "dev.architectury:architectury", version.ref = "architectury" } architectury = { module = "dev.architectury:architectury", version.ref = "architectury" }
rei_api = { module = "me.shedaniel:RoughlyEnoughItems-api", version.ref = "rei" } rei_api = { module = "me.shedaniel:RoughlyEnoughItems-api", version.ref = "rei" }
@@ -73,7 +76,7 @@ runtime_optional = [
"devauth", "devauth",
# "freecammod", # "freecammod",
"sodium", "sodium",
"qolify", # "qolify",
# "citresewn", # "citresewn",
# "ncr", # "ncr",
] ]

View File

@@ -8,7 +8,6 @@ pkgs.mkShell {
gh gh
git git
xdg-utils xdg-utils
temurin-bin-17
reuse reuse
pre-commit pre-commit
glfw glfw

View File

@@ -1,68 +0,0 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package moe.nea.firmament.mixins;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ArmorFeatureRenderer.class)
public abstract class ArmorTexturePatch<T extends LivingEntity, M extends BipedEntityModel<T>, A extends BipedEntityModel<T>> {
@Unique
private ItemStack lastRenderedArmorItem;
@Unique
private boolean foundCustomTexture;
@WrapWithCondition(method = "renderArmorParts", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/model/BipedEntityModel;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;IIFFFF)V"))
private boolean preventRenderingLeatherArmorColor(BipedEntityModel instance, MatrixStack matrixStack,
VertexConsumer vertexConsumer, int light, int uv,
float r, float g, float b, float a,
@Local(argsOnly = true) @Nullable String overlay) {
if (overlay != null) return true;
if (foundCustomTexture) return true;
var customOverlayTexture = CustomSkyBlockTextures.INSTANCE.getArmorTexture(this.lastRenderedArmorItem, false, "overlay");
return customOverlayTexture == null;
}
@Inject(method = "renderArmor", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;"))
private void onBeforeRenderArmor(MatrixStack matrices, VertexConsumerProvider vertexConsumers,
T entity, EquipmentSlot armorSlot, int light, A model, CallbackInfo ci,
@Local ItemStack itemStack) {
this.lastRenderedArmorItem = itemStack;
}
@Inject(method = "getArmorTexture", at = @At("HEAD"), cancellable = true)
private void onGetTexture(ArmorItem item, boolean secondLayer, String overlay, CallbackInfoReturnable<Identifier> cir) {
if (this.lastRenderedArmorItem == null) return;
var armorTexture = CustomSkyBlockTextures.INSTANCE.getArmorTexture(this.lastRenderedArmorItem, secondLayer, overlay);
if (armorTexture != null) {
cir.setReturnValue(armorTexture);
this.foundCustomTexture = true;
} else {
this.foundCustomTexture = false;
}
}
}

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -11,16 +12,17 @@ import moe.nea.firmament.features.fixes.Fixes;
import net.minecraft.client.gui.hud.ChatHud; import net.minecraft.client.gui.hud.ChatHud;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ChatHud.class) @Mixin(ChatHud.class)
public class ChatPeekingPatch { public class ChatPeekingPatch {
@ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;isChatFocused()Z")) @ModifyVariable(method = "render", at = @At(value = "HEAD"), index = 5, argsOnly = true)
public boolean onGetChatHud(boolean old) { public boolean onGetChatHud(boolean old) {
return old || Fixes.INSTANCE.shouldPeekChat(); return old || Fixes.INSTANCE.shouldPeekChat();
} }
@ModifyExpressionValue(method = "getHeight", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;isChatFocused()Z")) @ModifyExpressionValue(method = "getHeight()I", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;isChatFocused()Z"))
public boolean onGetChatHudHeight(boolean old) { public boolean onGetChatHudHeight(boolean old) {
return old || Fixes.INSTANCE.shouldPeekChat(); return old || Fixes.INSTANCE.shouldPeekChat();
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -11,6 +12,7 @@ import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
import net.minecraft.block.SkullBlock; import net.minecraft.block.SkullBlock;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer; import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer;
import net.minecraft.component.type.ProfileComponent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@@ -19,7 +21,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SkullBlockEntityRenderer.class) @Mixin(SkullBlockEntityRenderer.class)
public class CustomSkullTexturePatch { public class CustomSkullTexturePatch {
@Inject(method = "getRenderLayer", at = @At("HEAD"), cancellable = true) @Inject(method = "getRenderLayer", at = @At("HEAD"), cancellable = true)
private static void onGetRenderLayer(SkullBlock.SkullType type, GameProfile profile, CallbackInfoReturnable<RenderLayer> cir) { private static void onGetRenderLayer(SkullBlock.SkullType type, ProfileComponent profile, CallbackInfoReturnable<RenderLayer> cir) {
CustomSkyBlockTextures.INSTANCE.modifySkullTexture(type, profile, cir); CustomSkyBlockTextures.INSTANCE.modifySkullTexture(type, profile, cir);
} }
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -19,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(InGameHud.class) @Mixin(InGameHud.class)
public class HudRenderEvents { public class HudRenderEvents {
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getSleepTimer()I")) @Inject(method = "renderSleepOverlay", at = @At(value = "TAIL"))
public void renderCallBack(DrawContext context, float tickDelta, CallbackInfo ci) { public void renderCallBack(DrawContext context, float tickDelta, CallbackInfo ci) {
HudRenderEvent.Companion.publish(new HudRenderEvent(context, tickDelta)); HudRenderEvent.Companion.publish(new HudRenderEvent(context, tickDelta));
} }

View File

@@ -0,0 +1,26 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package moe.nea.firmament.mixins;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.mojang.serialization.Codec;
import net.minecraft.component.type.ProfileComponent;
import net.minecraft.util.Uuids;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import java.util.UUID;
@Mixin(ProfileComponent.class)
public class LenientProfileComponentPatch {
// lambda in RecordCodecBuilder.create for BASE_CODEC
@ModifyExpressionValue(method = "method_57508", at = @At(value = "FIELD", opcode = Opcodes.GETSTATIC, target = "Lnet/minecraft/util/Uuids;INT_STREAM_CODEC:Lcom/mojang/serialization/Codec;"))
private static Codec<UUID> onStaticInit(Codec<UUID> original) {
return Uuids.CODEC;
}
}

View File

@@ -1,11 +1,13 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
package moe.nea.firmament.mixins; package moe.nea.firmament.mixins;
import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.events.WorldRenderLastEvent; import moe.nea.firmament.events.WorldRenderLastEvent;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
@@ -24,11 +26,11 @@ public class WorldRenderLastEventPatch {
private BufferBuilderStorage bufferBuilders; private BufferBuilderStorage bufferBuilders;
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.BEFORE)) @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.BEFORE))
public void onWorldRenderLast(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) { public void onWorldRenderLast(float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci
, @Local MatrixStack matrixStack) {
var event = new WorldRenderLastEvent( var event = new WorldRenderLastEvent(
matrices, tickDelta, renderBlockOutline, matrixStack, tickDelta, renderBlockOutline,
camera, gameRenderer, lightmapTextureManager, camera, gameRenderer, lightmapTextureManager,
positionMatrix,
this.bufferBuilders.getEntityVertexConsumers() this.bufferBuilders.getEntityVertexConsumers()
); );
WorldRenderLastEvent.Companion.publish(event); WorldRenderLastEvent.Companion.publish(event);

View File

@@ -9,6 +9,7 @@ package moe.nea.firmament.mixins.custommodels;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.features.texturepack.BakedOverrideData; import moe.nea.firmament.features.texturepack.BakedOverrideData;
import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate; import moe.nea.firmament.features.texturepack.FirmamentModelPredicate;
import moe.nea.firmament.features.texturepack.ModelOverrideData; import moe.nea.firmament.features.texturepack.ModelOverrideData;
import net.minecraft.client.render.model.json.ModelOverride; import net.minecraft.client.render.model.json.ModelOverride;
@@ -38,11 +39,12 @@ public class TestForFirmamentOverridePredicatesPatch {
@ModifyExpressionValue(method = "apply", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/ModelOverrideList$BakedOverride;test([F)Z")) @ModifyExpressionValue(method = "apply", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/ModelOverrideList$BakedOverride;test([F)Z"))
public boolean testFirmamentOverrides(boolean originalValue, public boolean testFirmamentOverrides(boolean originalValue,
@Local ModelOverrideList.BakedOverride bakedOverride, @Local ModelOverrideList.BakedOverride bakedOverride,
@Local ItemStack stack) { @Local(argsOnly = true) ItemStack stack) {
if (!originalValue) return false; if (!originalValue) return false;
var overrideData = (BakedOverrideData) bakedOverride; var overrideData = (BakedOverrideData) bakedOverride;
var overrides = overrideData.getFirmamentOverrides(); var overrides = overrideData.getFirmamentOverrides();
if (overrides == null) return true; if (overrides == null) return true;
if (!CustomSkyBlockTextures.TConfig.INSTANCE.getEnableModelOverrides()) return false;
for (FirmamentModelPredicate firmamentOverride : overrides) { for (FirmamentModelPredicate firmamentOverride : overrides) {
if (!firmamentOverride.test(stack)) if (!firmamentOverride.test(stack))
return false; return false;

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -23,7 +24,7 @@ public class DisableCommonPacketWarnings {
@Inject(method = "warnOnUnknownPayload", at = @At("HEAD"), cancellable = true) @Inject(method = "warnOnUnknownPayload", at = @At("HEAD"), cancellable = true)
public void onCustomPacketError(CustomPayload customPayload, CallbackInfo ci) { public void onCustomPacketError(CustomPayload customPayload, CallbackInfo ci) {
if (Objects.equals(customPayload.id(), Identifier.of("badlion", "mods"))) { if (Objects.equals(customPayload.getId(), Identifier.of("badlion", "mods"))) {
ci.cancel(); ci.cancel();
} }
} }

View File

@@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package moe.nea.firmament.mixins.devenv;
import net.minecraft.client.util.Window;
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(Window.class)
public class IdentifyCloser {
@Inject(method = "close", at = @At("HEAD"))
public void onClose(CallbackInfo ci) {
Thread.dumpStack();
}
}

View File

@@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package moe.nea.firmament.mixins.devenv;
import net.minecraft.client.MinecraftClient;
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(MinecraftClient.class)
public class IdentifyStopperPatch {
@Inject(method = "scheduleStop", at = @At("HEAD"))
private void onStop(CallbackInfo ci) {
Thread.dumpStack();
}
}

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -137,8 +138,8 @@ object Firmament {
globalJob.cancel() globalJob.cancel()
}) })
registerFirmamentEvents() registerFirmamentEvents()
ItemTooltipCallback.EVENT.register { a, b, c -> ItemTooltipCallback.EVENT.register { a, b, c, d ->
ItemTooltipEvent.publish(ItemTooltipEvent(a, b, c)) ItemTooltipEvent.publish(ItemTooltipEvent(a, b, c, d))
} }
ScreenEvents.AFTER_INIT.register(ScreenEvents.AfterInit { client, screen, scaledWidth, scaledHeight -> ScreenEvents.AFTER_INIT.register(ScreenEvents.AfterInit { client, screen, scaledWidth, scaledHeight ->
ScreenEvents.afterRender(screen) ScreenEvents.afterRender(screen)

View File

@@ -1,17 +1,19 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
package moe.nea.firmament.events package moe.nea.firmament.events
import net.minecraft.client.item.TooltipContext import net.minecraft.client.item.TooltipType
import net.minecraft.item.Item.TooltipContext
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.text.Text import net.minecraft.text.Text
data class ItemTooltipEvent( data class ItemTooltipEvent(
val stack: ItemStack, val context: TooltipContext, val lines: MutableList<Text> val stack: ItemStack, val context: TooltipContext, val type: TooltipType, val lines: MutableList<Text>
) : FirmamentEvent() { ) : FirmamentEvent() {
companion object : FirmamentEventBus<ItemTooltipEvent>() companion object : FirmamentEventBus<ItemTooltipEvent>()
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -7,14 +8,14 @@
package moe.nea.firmament.events package moe.nea.firmament.events
import net.minecraft.client.gui.tooltip.Tooltip import net.minecraft.client.gui.tooltip.Tooltip
import net.minecraft.client.item.TooltipContext
import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.Item
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
data class TooltipEvent( data class TooltipEvent(
val itemStack: ItemStack, val itemStack: ItemStack,
val tooltip: Tooltip, val tooltip: Tooltip,
val tooltipContext: TooltipContext, val tooltipContext: Item.TooltipContext,
val player: PlayerEntity? val player: PlayerEntity?
) : FirmamentEvent() { ) : FirmamentEvent() {
companion object : FirmamentEventBus<TooltipEvent>() companion object : FirmamentEventBus<TooltipEvent>()

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -25,7 +26,6 @@ data class WorldRenderLastEvent(
val camera: Camera, val camera: Camera,
val gameRenderer: GameRenderer, val gameRenderer: GameRenderer,
val lightmapTextureManager: LightmapTextureManager, val lightmapTextureManager: LightmapTextureManager,
val positionMatrix: Matrix4f,
val vertexConsumers: VertexConsumerProvider.Immediate, val vertexConsumers: VertexConsumerProvider.Immediate,
) : FirmamentEvent() { ) : FirmamentEvent() {
companion object : FirmamentEventBus<WorldRenderLastEvent>() companion object : FirmamentEventBus<WorldRenderLastEvent>()

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -8,9 +9,9 @@ package moe.nea.firmament.features.debug
import net.minecraft.block.SkullBlock import net.minecraft.block.SkullBlock
import net.minecraft.block.entity.SkullBlockEntity import net.minecraft.block.entity.SkullBlockEntity
import net.minecraft.component.DataComponentTypes
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.item.Items import net.minecraft.item.Items
import net.minecraft.nbt.NbtHelper
import net.minecraft.text.Text import net.minecraft.text.Text
import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.hit.HitResult import net.minecraft.util.hit.HitResult
@@ -27,7 +28,6 @@ import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
import moe.nea.firmament.util.ClipboardUtils import moe.nea.firmament.util.ClipboardUtils
import moe.nea.firmament.util.MC import moe.nea.firmament.util.MC
import moe.nea.firmament.util.focusedItemStack import moe.nea.firmament.util.focusedItemStack
import moe.nea.firmament.util.getOrCreateCompoundTag
import moe.nea.firmament.util.skyBlockId import moe.nea.firmament.util.skyBlockId
object PowerUserTools : FirmamentFeature { object PowerUserTools : FirmamentFeature {
@@ -120,7 +120,8 @@ object PowerUserTools : FirmamentFeature {
lastCopiedStack = lastCopiedStack =
Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.modelid", model.toString())) Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.modelid", model.toString()))
} else if (it.matches(TConfig.copyNbtData)) { } else if (it.matches(TConfig.copyNbtData)) {
val nbt = item.orCreateNbt.toString() // TODO: copy full nbt
val nbt = item.get(DataComponentTypes.CUSTOM_DATA)?.nbt?.toString() ?: "<empty>"
ClipboardUtils.setTextContent(nbt) ClipboardUtils.setTextContent(nbt)
lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.nbt")) lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.nbt"))
} else if (it.matches(TConfig.copySkullTexture)) { } else if (it.matches(TConfig.copySkullTexture)) {
@@ -128,7 +129,7 @@ object PowerUserTools : FirmamentFeature {
lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-skull")) lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-skull"))
return@subscribe return@subscribe
} }
val profile = NbtHelper.toGameProfile(item.orCreateNbt.getOrCreateCompoundTag("SkullOwner")) val profile = item.get(DataComponentTypes.PROFILE)
if (profile == null) { if (profile == null) {
lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-profile")) lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-profile"))
return@subscribe return@subscribe
@@ -140,7 +141,10 @@ object PowerUserTools : FirmamentFeature {
} }
ClipboardUtils.setTextContent(skullTexture.toString()) ClipboardUtils.setTextContent(skullTexture.toString())
lastCopiedStack = lastCopiedStack =
Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.skull-id", skullTexture.toString())) Pair(
item,
Text.stringifiedTranslatable("firmament.tooltip.copied.skull-id", skullTexture.toString())
)
println("Copied skull id: $skullTexture") println("Copied skull id: $skullTexture")
} }
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -9,7 +10,6 @@ package moe.nea.firmament.features.inventory
import java.awt.Color import java.awt.Color
import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.DrawContext
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtElement
import net.minecraft.util.Formatting import net.minecraft.util.Formatting
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import moe.nea.firmament.events.HotbarItemRenderEvent import moe.nea.firmament.events.HotbarItemRenderEvent
@@ -17,6 +17,8 @@ import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.util.MC import moe.nea.firmament.util.MC
import moe.nea.firmament.util.item.loreAccordingToNbt
import moe.nea.firmament.util.unformattedString
object ItemRarityCosmetics : FirmamentFeature { object ItemRarityCosmetics : FirmamentFeature {
override val identifier: String override val identifier: String
@@ -47,9 +49,7 @@ object ItemRarityCosmetics : FirmamentFeature {
} }
private val ItemStack.skyblockLoreRarityColor: Triple<Float, Float, Float>? private val ItemStack.skyblockLoreRarityColor: Triple<Float, Float, Float>?
get() { get() {
val lore = val entry = loreAccordingToNbt.lastOrNull()?.unformattedString ?: ""
getOrCreateSubNbt(ItemStack.DISPLAY_KEY).getList(ItemStack.LORE_KEY, NbtElement.STRING_TYPE.toInt())
val entry = lore.getString(lore.size - 1)
return rarityToColor.entries.find { (k, v) -> k in entry }?.value return rarityToColor.entries.find { (k, v) -> k in entry }?.value
} }

View File

@@ -1,8 +1,10 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@file:UseSerializers(DashlessUUIDSerializer::class) @file:UseSerializers(DashlessUUIDSerializer::class)
package moe.nea.firmament.features.inventory package moe.nea.firmament.features.inventory
@@ -90,7 +92,7 @@ object SlotLocking : FirmamentFeature {
if (sellItem == null) return false if (sellItem == null) return false
if (sellItem.displayNameAccordingToNbt?.unformattedString == "Sell Item") return true if (sellItem.displayNameAccordingToNbt?.unformattedString == "Sell Item") return true
val lore = sellItem.loreAccordingToNbt val lore = sellItem.loreAccordingToNbt
return (lore.lastOrNull() ?: return false).value?.unformattedString == "Click to buyback!" return (lore.lastOrNull() ?: return false).unformattedString == "Click to buyback!"
} }
override fun onLoad() { override fun onLoad() {

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -22,6 +23,7 @@ import net.minecraft.nbt.NbtList
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import net.minecraft.nbt.NbtSizeTracker import net.minecraft.nbt.NbtSizeTracker
import moe.nea.firmament.util.MC
@Serializable(with = VirtualInventory.Serializer::class) @Serializable(with = VirtualInventory.Serializer::class)
data class VirtualInventory( data class VirtualInventory(
@@ -44,13 +46,13 @@ data class VirtualInventory(
val s = decoder.decodeString() val s = decoder.decodeString()
val n = NbtIo.readCompressed(ByteArrayInputStream(s.decodeBase64Bytes()), NbtSizeTracker.of(100_000_000)) val n = NbtIo.readCompressed(ByteArrayInputStream(s.decodeBase64Bytes()), NbtSizeTracker.of(100_000_000))
val items = n.getList(INVENTORY, NbtCompound.COMPOUND_TYPE.toInt()) val items = n.getList(INVENTORY, NbtCompound.COMPOUND_TYPE.toInt())
return VirtualInventory(items.map { ItemStack.fromNbt(it as NbtCompound) }) return VirtualInventory(items.map { ItemStack.fromNbtOrEmpty(MC.defaultRegistries, it as NbtCompound) })
} }
override fun serialize(encoder: Encoder, value: VirtualInventory) { override fun serialize(encoder: Encoder, value: VirtualInventory) {
val list = NbtList() val list = NbtList()
value.stacks.forEach { value.stacks.forEach {
list.add(NbtCompound().also(it::writeNbt)) list.add(it.encode(MC.defaultRegistries))
} }
val baos = ByteArrayOutputStream() val baos = ByteArrayOutputStream()
NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos) NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos)

View File

@@ -91,11 +91,9 @@ object PickaxeAbility : FirmamentFeature {
DurabilityBarEvent.subscribe { DurabilityBarEvent.subscribe {
if (!TConfig.drillFuelBar) return@subscribe if (!TConfig.drillFuelBar) return@subscribe
val lore = it.item.loreAccordingToNbt val lore = it.item.loreAccordingToNbt
if (lore.lastOrNull()?.value?.unformattedString?.contains("DRILL") != true) return@subscribe if (lore.lastOrNull()?.unformattedString?.contains("DRILL") != true) return@subscribe
val maxFuel = lore.firstNotNullOfOrNull { val maxFuel = lore.firstNotNullOfOrNull {
fuelPattern.useMatch( fuelPattern.useMatch(it.unformattedString) {
it.value?.unformattedString ?: return@firstNotNullOfOrNull null
) {
parseShortNumber(group("maxFuel")) parseShortNumber(group("maxFuel"))
} }
} ?: return@subscribe } ?: return@subscribe
@@ -115,7 +113,7 @@ object PickaxeAbility : FirmamentFeature {
if (MC.screen?.title?.unformattedString == "Heart of the Mountain") { if (MC.screen?.title?.unformattedString == "Heart of the Mountain") {
val name = it.stack.displayNameAccordingToNbt?.unformattedString ?: return@subscribe val name = it.stack.displayNameAccordingToNbt?.unformattedString ?: return@subscribe
val cooldown = it.stack.loreAccordingToNbt.firstNotNullOfOrNull { val cooldown = it.stack.loreAccordingToNbt.firstNotNullOfOrNull {
cooldownPattern.useMatch(it.value?.unformattedString ?: return@firstNotNullOfOrNull null) { cooldownPattern.useMatch(it.unformattedString) {
parseTimePattern(group("cooldown")) parseTimePattern(group("cooldown"))
} }
} ?: return@subscribe } ?: return@subscribe
@@ -134,15 +132,15 @@ object PickaxeAbility : FirmamentFeature {
fun getCooldownFromLore(itemStack: ItemStack): PickaxeAbilityData? { fun getCooldownFromLore(itemStack: ItemStack): PickaxeAbilityData? {
val lore = itemStack.loreAccordingToNbt val lore = itemStack.loreAccordingToNbt
if (!lore.any { it.value?.unformattedString?.contains("Breaking Power") == true }) if (!lore.any { it.unformattedString.contains("Breaking Power") == true })
return null return null
val cooldown = lore.firstNotNullOfOrNull { val cooldown = lore.firstNotNullOfOrNull {
cooldownPattern.useMatch(it.value?.unformattedString ?: return@firstNotNullOfOrNull null) { cooldownPattern.useMatch(it.unformattedString) {
parseTimePattern(group("cooldown")) parseTimePattern(group("cooldown"))
} }
} ?: return null } ?: return null
val name = lore.firstNotNullOfOrNull { val name = lore.firstNotNullOfOrNull {
abilityPattern.useMatch(it.value?.unformattedString ?: return@firstNotNullOfOrNull null) { abilityPattern.useMatch(it.unformattedString) {
group("name") group("name")
} }
} ?: return null } ?: return null

View File

@@ -7,21 +7,20 @@
package moe.nea.firmament.features.texturepack package moe.nea.firmament.features.texturepack
import com.mojang.authlib.GameProfile
import com.mojang.authlib.minecraft.MinecraftProfileTexture import com.mojang.authlib.minecraft.MinecraftProfileTexture
import com.mojang.authlib.properties.Property
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
import net.minecraft.block.SkullBlock import net.minecraft.block.SkullBlock
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.render.RenderLayer import net.minecraft.client.render.RenderLayer
import net.minecraft.client.util.ModelIdentifier import net.minecraft.client.util.ModelIdentifier
import net.minecraft.item.ItemStack import net.minecraft.component.type.ProfileComponent
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import moe.nea.firmament.events.CustomItemModelEvent import moe.nea.firmament.events.CustomItemModelEvent
import moe.nea.firmament.events.TickEvent import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.util.IdentityCharacteristics import moe.nea.firmament.util.IdentityCharacteristics
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.item.decodeProfileTextureProperty import moe.nea.firmament.util.item.decodeProfileTextureProperty
import moe.nea.firmament.util.skyBlockId import moe.nea.firmament.util.skyBlockId
@@ -53,12 +52,12 @@ object CustomSkyBlockTextures : FirmamentFeature {
} }
} }
private val skullTextureCache = mutableMapOf<IdentityCharacteristics<GameProfile>, Any>() private val skullTextureCache = mutableMapOf<IdentityCharacteristics<ProfileComponent>, Any>()
private val sentinelPresentInvalid = Object() private val sentinelPresentInvalid = Object()
private val mcUrlRegex = "https?://textures.minecraft.net/texture/([a-fA-F0-9]+)".toRegex() private val mcUrlRegex = "https?://textures.minecraft.net/texture/([a-fA-F0-9]+)".toRegex()
fun getSkullId(profile: GameProfile): String? {
val textureProperty = MC.instance.sessionService.getPackedTextures(profile) ?: return null fun getSkullId(textureProperty: Property): String? {
val texture = decodeProfileTextureProperty(textureProperty) ?: return null val texture = decodeProfileTextureProperty(textureProperty) ?: return null
val textureUrl = val textureUrl =
texture.textures[MinecraftProfileTexture.Type.SKIN]?.url ?: return null texture.textures[MinecraftProfileTexture.Type.SKIN]?.url ?: return null
@@ -66,40 +65,23 @@ object CustomSkyBlockTextures : FirmamentFeature {
return mcUrlData.groupValues[1] return mcUrlData.groupValues[1]
} }
fun getSkullTexture(profile: GameProfile): Identifier? { fun getSkullTexture(profile: ProfileComponent): Identifier? {
val id = getSkullId(profile) ?: return null val id = getSkullId(profile.properties["textures"].firstOrNull() ?: return null) ?: return null
return Identifier("firmskyblock", "textures/placedskull/$id.png") return Identifier("firmskyblock", "textures/placedskull/$id.png")
} }
fun getArmorTexture(
itemStack: ItemStack, secondLayer: Boolean,
overlay: String?
): Identifier? {
val modelIdentifier = CustomItemModelEvent.getModelIdentifier(itemStack) ?: return null
// Vanilla scheme: "textures/models/armor/" + var10000 + "_layer_" + (secondLayer ? 2 : 1) + (overlay == null ? "" : "_" + overlay) + ".png";
val overlayPart = if (overlay != null) "_$overlay" else ""
val identifier = Identifier(
modelIdentifier.namespace,
"textures/models/armor/${modelIdentifier.path}_layer_${if (secondLayer) 2 else 1}$overlayPart.png"
)
if (MC.resourceManager.getResource(identifier).isPresent) {
return identifier
}
return null
}
fun modifySkullTexture( fun modifySkullTexture(
type: SkullBlock.SkullType?, type: SkullBlock.SkullType?,
profile: GameProfile?, component: ProfileComponent?,
cir: CallbackInfoReturnable<RenderLayer> cir: CallbackInfoReturnable<RenderLayer>
) { ) {
if (type != SkullBlock.Type.PLAYER) return if (type != SkullBlock.Type.PLAYER) return
if (!TConfig.skullsEnabled) return if (!TConfig.skullsEnabled) return
if (profile == null) return if (component == null) return
val ic = IdentityCharacteristics(profile) val ic = IdentityCharacteristics(component)
val n = skullTextureCache.getOrPut(ic) { val n = skullTextureCache.getOrPut(ic) {
val id = getSkullTexture(profile) ?: return@getOrPut sentinelPresentInvalid val id = getSkullTexture(component) ?: return@getOrPut sentinelPresentInvalid
if (!MinecraftClient.getInstance().resourceManager.getResource(id).isPresent) { if (!MinecraftClient.getInstance().resourceManager.getResource(id).isPresent) {
return@getOrPut sentinelPresentInvalid return@getOrPut sentinelPresentInvalid
} }

View File

@@ -10,14 +10,13 @@ import com.google.gson.JsonElement
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtElement import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtString import net.minecraft.nbt.NbtString
import moe.nea.firmament.util.item.displayNameAccordingToNbt
import moe.nea.firmament.util.item.loreAccordingToNbt
data class DisplayNamePredicate(val stringMatcher: StringMatcher) : FirmamentModelPredicate { data class DisplayNamePredicate(val stringMatcher: StringMatcher) : FirmamentModelPredicate {
override fun test(stack: ItemStack): Boolean { override fun test(stack: ItemStack): Boolean {
val display = stack.getOrCreateSubNbt(ItemStack.DISPLAY_KEY) val display = stack.displayNameAccordingToNbt
return if (display.contains(ItemStack.NAME_KEY, NbtElement.STRING_TYPE.toInt())) return stringMatcher.matches(display)
stringMatcher.matches(display.get(ItemStack.NAME_KEY) as NbtString)
else
false
} }
object Parser : FirmamentModelPredicateParser { object Parser : FirmamentModelPredicateParser {

View File

@@ -8,8 +8,7 @@ package moe.nea.firmament.features.texturepack
import com.google.gson.JsonElement import com.google.gson.JsonElement
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtElement import moe.nea.firmament.util.item.loreAccordingToNbt
import net.minecraft.nbt.NbtString
class LorePredicate(val matcher: StringMatcher) : FirmamentModelPredicate { class LorePredicate(val matcher: StringMatcher) : FirmamentModelPredicate {
object Parser : FirmamentModelPredicateParser { object Parser : FirmamentModelPredicateParser {
@@ -19,10 +18,7 @@ class LorePredicate(val matcher: StringMatcher) : FirmamentModelPredicate {
} }
override fun test(stack: ItemStack): Boolean { override fun test(stack: ItemStack): Boolean {
val display = stack.getOrCreateSubNbt(ItemStack.DISPLAY_KEY) val lore = stack.loreAccordingToNbt
if (!display.contains(ItemStack.LORE_KEY, NbtElement.LIST_TYPE.toInt())) return lore.any { matcher.matches(it) }
return false
val lore = display.getList(ItemStack.LORE_KEY, NbtElement.STRING_TYPE.toInt())
return lore.any { matcher.matches(it as NbtString)}
} }
} }

View File

@@ -12,6 +12,7 @@ import com.google.gson.JsonPrimitive
import java.util.function.Predicate import java.util.function.Predicate
import net.minecraft.nbt.NbtString import net.minecraft.nbt.NbtString
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.removeColorCodes import moe.nea.firmament.util.removeColorCodes
interface StringMatcher { interface StringMatcher {
@@ -27,7 +28,7 @@ interface StringMatcher {
val isString = stringStart >= 0 && string.subSequence(0, stringStart).isBlank() val isString = stringStart >= 0 && string.subSequence(0, stringStart).isBlank()
val isJson = jsonStart >= 0 && string.subSequence(0, jsonStart).isBlank() val isJson = jsonStart >= 0 && string.subSequence(0, jsonStart).isBlank()
if (isString || isJson) if (isString || isJson)
return matches(Text.Serialization.fromJson(string) ?: return false) return matches(Text.Serialization.fromJson(string, MC.defaultRegistries) ?: return false)
return matches(string) return matches(string)
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -11,7 +12,7 @@ import io.github.cottonmc.cotton.gui.client.BackgroundPainter
import io.github.cottonmc.cotton.gui.widget.TooltipBuilder import io.github.cottonmc.cotton.gui.widget.TooltipBuilder
import io.github.cottonmc.cotton.gui.widget.WWidget import io.github.cottonmc.cotton.gui.widget.WWidget
import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.DrawContext
import net.minecraft.client.item.TooltipContext import net.minecraft.client.item.TooltipType
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.util.MC import moe.nea.firmament.util.MC
@@ -32,7 +33,7 @@ open class WTitledItem(var stack: ItemStack, val countString: Text = Text.empty(
} }
override fun addTooltip(tooltip: TooltipBuilder) { override fun addTooltip(tooltip: TooltipBuilder) {
tooltip.add(*stack.getTooltip(null, TooltipContext.BASIC).toTypedArray()) tooltip.add(*stack.getTooltip(null, null, TooltipType.BASIC).toTypedArray())
} }
} }

View File

@@ -136,7 +136,7 @@ object EntityRenderer {
posY, posY,
posX + 50, posX + 50,
posY + 80, posY + 80,
(minOf(2F / maxSize, 1F) * 30).toInt(), minOf(2F / maxSize, 1F) * 30,
-bottomOffset, -bottomOffset,
mouseX, mouseX,
mouseY, mouseY,
@@ -155,7 +155,7 @@ object EntityRenderer {
y1: Int, y1: Int,
x2: Int, x2: Int,
y2: Int, y2: Int,
size: Int, size: Float,
bottomOffset: Float, bottomOffset: Float,
mouseX: Float, mouseX: Float,
mouseY: Float, mouseY: Float,

View File

@@ -16,11 +16,13 @@ import kotlin.jvm.optionals.getOrNull
import kotlin.streams.asSequence import kotlin.streams.asSequence
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.world.ClientWorld import net.minecraft.component.type.MapIdComponent
import net.minecraft.entity.Entity import net.minecraft.entity.Entity
import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerEntity
import net.minecraft.fluid.Fluid import net.minecraft.fluid.Fluid
import net.minecraft.item.map.MapState import net.minecraft.item.map.MapState
import net.minecraft.recipe.BrewingRecipeRegistry
import net.minecraft.recipe.Ingredient
import net.minecraft.recipe.RecipeManager import net.minecraft.recipe.RecipeManager
import net.minecraft.registry.BuiltinRegistries import net.minecraft.registry.BuiltinRegistries
import net.minecraft.registry.DynamicRegistryManager import net.minecraft.registry.DynamicRegistryManager
@@ -29,10 +31,10 @@ import net.minecraft.registry.RegistryKey
import net.minecraft.registry.RegistryKeys import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.RegistryWrapper import net.minecraft.registry.RegistryWrapper
import net.minecraft.registry.entry.RegistryEntry import net.minecraft.registry.entry.RegistryEntry
import net.minecraft.registry.entry.RegistryEntryInfo
import net.minecraft.registry.entry.RegistryEntryList import net.minecraft.registry.entry.RegistryEntryList
import net.minecraft.registry.entry.RegistryEntryOwner import net.minecraft.registry.entry.RegistryEntryOwner
import net.minecraft.registry.tag.TagKey import net.minecraft.registry.tag.TagKey
import net.minecraft.resource.featuretoggle.FeatureFlag
import net.minecraft.resource.featuretoggle.FeatureFlags import net.minecraft.resource.featuretoggle.FeatureFlags
import net.minecraft.resource.featuretoggle.FeatureSet import net.minecraft.resource.featuretoggle.FeatureSet
import net.minecraft.scoreboard.Scoreboard import net.minecraft.scoreboard.Scoreboard
@@ -119,6 +121,10 @@ fun <T> makeRegistry(registryWrapper: RegistryWrapper.Impl<T>, key: RegistryKey<
return key return key
} }
override fun getEntryInfo(key: RegistryKey<T>?): Optional<RegistryEntryInfo> {
TODO("Not yet implemented")
}
override fun getLifecycle(): Lifecycle { override fun getLifecycle(): Lifecycle {
return Lifecycle.stable() return Lifecycle.stable()
} }
@@ -194,18 +200,18 @@ fun <T> makeRegistry(registryWrapper: RegistryWrapper.Impl<T>, key: RegistryKey<
return registryWrapper.getOptional(key ?: return Optional.empty()) return registryWrapper.getOptional(key ?: return Optional.empty())
} }
override fun getEntry(id: Identifier?): Optional<RegistryEntry.Reference<T>> {
TODO("Not yet implemented")
}
override fun createEntry(value: T): RegistryEntry.Reference<T> { override fun createEntry(value: T): RegistryEntry.Reference<T> {
TODO() TODO("Not yet implemented")
} }
override fun contains(key: RegistryKey<T>?): Boolean { override fun contains(key: RegistryKey<T>?): Boolean {
return getEntry(key).isPresent return getEntry(key).isPresent
} }
override fun getEntryLifecycle(entry: T): Lifecycle {
return Lifecycle.stable()
}
override fun getId(value: T): Identifier? { override fun getId(value: T): Identifier? {
return (inverseLookup[value] ?: return null).value return (inverseLookup[value] ?: return null).value
} }
@@ -236,7 +242,9 @@ fun createDynamicRegistry(): DynamicRegistryManager.Immutable {
} }
} }
class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegistry()) : World( class FakeWorld(
registries: DynamicRegistryManager.Immutable = createDynamicRegistry(),
) : World(
Properties, Properties,
RegistryKey.of(RegistryKeys.WORLD, Identifier.of("firmament", "fakeworld")), RegistryKey.of(RegistryKeys.WORLD, Identifier.of("firmament", "fakeworld")),
registries, registries,
@@ -252,16 +260,8 @@ class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegi
0, 0 0, 0
) { ) {
object Properties : MutableWorldProperties { object Properties : MutableWorldProperties {
override fun getSpawnX(): Int { override fun getSpawnPos(): BlockPos {
return 0 return BlockPos.ORIGIN
}
override fun getSpawnY(): Int {
return 0
}
override fun getSpawnZ(): Int {
return 0
} }
override fun getSpawnAngle(): Float { override fun getSpawnAngle(): Float {
@@ -303,17 +303,7 @@ class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegi
return false return false
} }
override fun setSpawnX(spawnX: Int) { override fun setSpawnPos(pos: BlockPos?, angle: Float) {}
}
override fun setSpawnY(spawnY: Int) {
}
override fun setSpawnZ(spawnZ: Int) {
}
override fun setSpawnAngle(spawnAngle: Float) {
}
} }
override fun getPlayers(): List<PlayerEntity> { override fun getPlayers(): List<PlayerEntity> {
@@ -361,7 +351,11 @@ class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegi
class FakeChunkManager(val world: FakeWorld) : ChunkManager() { class FakeChunkManager(val world: FakeWorld) : ChunkManager() {
override fun getChunk(x: Int, z: Int, leastStatus: ChunkStatus?, create: Boolean): Chunk { override fun getChunk(x: Int, z: Int, leastStatus: ChunkStatus?, create: Boolean): Chunk {
return EmptyChunk(world, ChunkPos(x,z), world.registryManager.get(RegistryKeys.BIOME).entryOf(BiomeKeys.PLAINS)) return EmptyChunk(
world,
ChunkPos(x, z),
world.registryManager.get(RegistryKeys.BIOME).entryOf(BiomeKeys.PLAINS)
)
} }
override fun getWorld(): BlockView { override fun getWorld(): BlockView {
@@ -406,7 +400,7 @@ class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegi
override fun syncWorldEvent(player: PlayerEntity?, eventId: Int, pos: BlockPos?, data: Int) { override fun syncWorldEvent(player: PlayerEntity?, eventId: Int, pos: BlockPos?, data: Int) {
} }
override fun emitGameEvent(event: GameEvent?, emitterPos: Vec3d?, emitter: GameEvent.Emitter?) { override fun emitGameEvent(event: RegistryEntry<GameEvent>?, emitterPos: Vec3d?, emitter: GameEvent.Emitter?) {
} }
override fun updateListeners(pos: BlockPos?, oldState: BlockState?, newState: BlockState?, flags: Int) { override fun updateListeners(pos: BlockPos?, oldState: BlockState?, newState: BlockState?, flags: Int) {
@@ -435,15 +429,15 @@ class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegi
return TickManager() return TickManager()
} }
override fun getMapState(id: String?): MapState? { override fun getMapState(id: MapIdComponent?): MapState? {
return null return null
} }
override fun putMapState(id: String?, state: MapState?) { override fun putMapState(id: MapIdComponent?, state: MapState?) {
} }
override fun getNextMapId(): Int { override fun getNextMapId(): MapIdComponent {
return 0 return MapIdComponent(0)
} }
override fun setBlockBreakingInfo(entityId: Int, pos: BlockPos?, progress: Int) { override fun setBlockBreakingInfo(entityId: Int, pos: BlockPos?, progress: Int) {
@@ -454,7 +448,7 @@ class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegi
} }
override fun getRecipeManager(): RecipeManager { override fun getRecipeManager(): RecipeManager {
return RecipeManager() return RecipeManager(registryManager)
} }
object FakeEntityLookup : EntityLookup<Entity> { object FakeEntityLookup : EntityLookup<Entity> {
@@ -488,4 +482,8 @@ class FakeWorld(registries: DynamicRegistryManager.Immutable = createDynamicRegi
override fun getEntityLookup(): EntityLookup<Entity> { override fun getEntityLookup(): EntityLookup<Entity> {
return FakeEntityLookup return FakeEntityLookup
} }
override fun getBrewingRecipeRegistry(): BrewingRecipeRegistry {
return BrewingRecipeRegistry.EMPTY
}
} }

View File

@@ -7,9 +7,11 @@
package moe.nea.firmament.gui.entity package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject import com.google.gson.JsonObject
import net.minecraft.component.DataComponentTypes
import net.minecraft.component.type.DyedColorComponent
import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.EquipmentSlot
import net.minecraft.entity.LivingEntity import net.minecraft.entity.LivingEntity
import net.minecraft.item.DyeableArmorItem import net.minecraft.item.ArmorItem
import net.minecraft.item.Item import net.minecraft.item.Item
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.item.Items import net.minecraft.item.Items
@@ -51,9 +53,8 @@ object ModifyEquipment : EntityModifier {
} }
private fun coloredLeatherArmor(leatherArmor: Item, data: String): ItemStack { private fun coloredLeatherArmor(leatherArmor: Item, data: String): ItemStack {
require(leatherArmor is DyeableArmorItem)
val stack = ItemStack(leatherArmor) val stack = ItemStack(leatherArmor)
leatherArmor.setColor(stack, data.toInt(16)) stack.set(DataComponentTypes.DYED_COLOR, DyedColorComponent(data.toInt(16), false))
return stack return stack
} }
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -12,9 +13,6 @@ import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription
import io.github.cottonmc.cotton.gui.widget.WGridPanel import io.github.cottonmc.cotton.gui.widget.WGridPanel
import io.github.cottonmc.cotton.gui.widget.WText import io.github.cottonmc.cotton.gui.widget.WText
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
import moe.nea.firmament.gui.WTitledItem
import moe.nea.firmament.util.ScreenUtil
import moe.nea.firmament.util.modifyLore
import moe.nea.lisp.LispData import moe.nea.lisp.LispData
import moe.nea.lisp.LispExecutionContext import moe.nea.lisp.LispExecutionContext
import moe.nea.lisp.LispParser import moe.nea.lisp.LispParser
@@ -23,16 +21,20 @@ import moe.nea.lisp.bind.LispBinding
import moe.nea.lisp.bind.UnmapForeignObject import moe.nea.lisp.bind.UnmapForeignObject
import net.minecraft.command.argument.ItemStringReader import net.minecraft.command.argument.ItemStringReader
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.registry.Registries
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.gui.WTitledItem
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.ScreenUtil
import moe.nea.firmament.util.item.setCustomName
import moe.nea.firmament.util.modifyLore
class ProfileViewerLibrary { class ProfileViewerLibrary {
@LispBinding("mk-item") @LispBinding("mk-item")
fun makeItem(itemType: String, title: String, vararg lore: String): LispData.ForeignObject<ItemStack> { fun makeItem(itemType: String, title: String, vararg lore: String): LispData.ForeignObject<ItemStack> {
val item = ItemStringReader.item(Registries.ITEM.readOnlyWrapper, StringReader(itemType)) val item = ItemStringReader(MC.defaultRegistries).consume(StringReader(itemType))
val itemStack = ItemStack(item.item.value()) val itemStack = ItemStack(item.item.value())
itemStack.nbt = item.nbt itemStack.applyComponentsFrom(item.components)
itemStack.modifyLore { lore.map { Text.literal(it) } } itemStack.modifyLore { lore.map { Text.literal(it) } }
itemStack.setCustomName(Text.literal(title)) itemStack.setCustomName(Text.literal(title))
return LispData.ForeignObject(itemStack) return LispData.ForeignObject(itemStack)

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -32,6 +33,7 @@ import net.minecraft.text.Style
import net.minecraft.text.Text import net.minecraft.text.Text
import net.minecraft.util.DyeColor import net.minecraft.util.DyeColor
import net.minecraft.util.Formatting import net.minecraft.util.Formatting
import moe.nea.firmament.util.item.setCustomName
object SkillPage : ProfilePage { object SkillPage : ProfilePage {

View File

@@ -1,6 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2018-2023 shedaniel <daniel@shedaniel.me> * SPDX-FileCopyrightText: 2018-2023 shedaniel <daniel@shedaniel.me>
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
@@ -17,16 +18,19 @@ import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer
import me.shedaniel.rei.api.client.gui.widgets.Tooltip import me.shedaniel.rei.api.client.gui.widgets.Tooltip
import me.shedaniel.rei.api.client.gui.widgets.TooltipContext import me.shedaniel.rei.api.client.gui.widgets.TooltipContext
import me.shedaniel.rei.api.common.entry.EntryStack import me.shedaniel.rei.api.common.entry.EntryStack
import moe.nea.firmament.rei.FirmamentReiPlugin.Companion.asItemEntry
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.DrawContext
import net.minecraft.client.item.TooltipType
import net.minecraft.client.render.DiffuseLighting import net.minecraft.client.render.DiffuseLighting
import net.minecraft.client.render.LightmapTextureManager
import net.minecraft.client.render.OverlayTexture import net.minecraft.client.render.OverlayTexture
import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.json.ModelTransformationMode import net.minecraft.client.render.model.json.ModelTransformationMode
import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.texture.SpriteAtlasTexture
import net.minecraft.item.Item
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import moe.nea.firmament.rei.FirmamentReiPlugin.Companion.asItemEntry
object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<SBItemStack, BakedModel> { object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<SBItemStack, BakedModel> {
override fun render( override fun render(
@@ -43,7 +47,13 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
val minecraft = MinecraftClient.getInstance() val minecraft = MinecraftClient.getInstance()
override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? { override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? {
return entry.asItemEntry().getTooltip(tooltipContext, false) return Tooltip.create(
entry.asItemEntry().value.getTooltip(
Item.TooltipContext.DEFAULT,
null,
TooltipType.BASIC
)
)
} }
override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel { override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel {
@@ -60,11 +70,11 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
graphics: DrawContext, graphics: DrawContext,
delta: Float delta: Float
) { ) {
setupGL(model)
val modelViewStack = RenderSystem.getModelViewStack() val modelViewStack = RenderSystem.getModelViewStack()
modelViewStack.push() modelViewStack.pushMatrix()
modelViewStack.scale(20.0f, -20.0f, 1.0f) modelViewStack.scale(20.0f, 20.0f, 1.0f)
RenderSystem.applyModelViewMatrix() RenderSystem.applyModelViewMatrix()
setupGL(model)
} }
fun setupGL(model: BakedModel) { fun setupGL(model: BakedModel) {
@@ -93,10 +103,10 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
if (entry.isEmpty) return if (entry.isEmpty) return
val value = entry.asItemEntry().value val value = entry.asItemEntry().value
graphics.matrices.push() graphics.matrices.push()
graphics.matrices.translate(bounds.centerX.toFloat() / 20.0f, bounds!!.centerY.toFloat() / -20.0f, 0.0f) graphics.matrices.translate(bounds.centerX.toFloat() / 20.0f, bounds.centerY.toFloat() / 20.0f, 0.0f)
graphics.matrices.scale( graphics.matrices.scale(
bounds.getWidth().toFloat() / 20.0f, bounds.getWidth().toFloat() / 20.0f,
(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 20.0f, -(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 20.0f,
1.0f 1.0f
) )
minecraft minecraft
@@ -107,7 +117,7 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
false, false,
graphics.matrices, graphics.matrices,
immediate, immediate,
15728880, LightmapTextureManager.MAX_LIGHT_COORDINATE,
OverlayTexture.DEFAULT_UV, OverlayTexture.DEFAULT_UV,
model model
) )
@@ -121,9 +131,9 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
graphics: DrawContext, graphics: DrawContext,
delta: Float delta: Float
) { ) {
this.endGL(model) RenderSystem.getModelViewStack().popMatrix()
RenderSystem.getModelViewStack().pop()
RenderSystem.applyModelViewMatrix() RenderSystem.applyModelViewMatrix()
this.endGL(model)
} }
fun endGL(model: BakedModel) { fun endGL(model: BakedModel) {
@@ -145,19 +155,20 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
delta: Float delta: Float
) { ) {
val modelViewStack = RenderSystem.getModelViewStack() val modelViewStack = RenderSystem.getModelViewStack()
modelViewStack.push() modelViewStack.pushMatrix()
modelViewStack.multiplyPositionMatrix(graphics.matrices.peek().positionMatrix) modelViewStack.mul(graphics.matrices.peek().positionMatrix)
modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0.0f) modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0.0f)
modelViewStack.scale( modelViewStack.scale(
bounds.width.toFloat() / 16.0f, bounds.width.toFloat() / 16.0f,
(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 16.0f, -(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 16.0f,
1.0f 1.0f
) )
RenderSystem.applyModelViewMatrix() RenderSystem.applyModelViewMatrix()
renderOverlay(DrawContext(minecraft, graphics.vertexConsumers), entry.asItemEntry()) renderOverlay(DrawContext(minecraft, graphics.vertexConsumers), entry.asItemEntry())
modelViewStack.pop() modelViewStack.popMatrix()
RenderSystem.applyModelViewMatrix() RenderSystem.applyModelViewMatrix()
} }
fun renderOverlay(graphics: DrawContext, entry: EntryStack<ItemStack>) { fun renderOverlay(graphics: DrawContext, entry: EntryStack<ItemStack>) {
if (!entry.isEmpty) { if (!entry.isEmpty) {
graphics.drawItemInSlot(MinecraftClient.getInstance().textRenderer, entry.value, 0, 0, null) graphics.drawItemInSlot(MinecraftClient.getInstance().textRenderer, entry.value, 0, 0, null)

View File

@@ -1,13 +1,12 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
package moe.nea.firmament.repo package moe.nea.firmament.repo
import com.mojang.authlib.GameProfile
import com.mojang.authlib.minecraft.MinecraftProfileTexture
import com.mojang.serialization.Dynamic import com.mojang.serialization.Dynamic
import io.github.cottonmc.cotton.gui.client.CottonHud import io.github.cottonmc.cotton.gui.client.CottonHud
import io.github.moulberry.repo.IReloadable import io.github.moulberry.repo.IReloadable
@@ -19,28 +18,27 @@ import java.util.concurrent.ConcurrentHashMap
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.jvm.optionals.getOrNull
import net.minecraft.SharedConstants import net.minecraft.SharedConstants
import net.minecraft.block.entity.SkullBlockEntity
import net.minecraft.client.resource.language.I18n import net.minecraft.client.resource.language.I18n
import net.minecraft.component.DataComponentTypes
import net.minecraft.component.type.NbtComponent
import net.minecraft.datafixer.Schemas import net.minecraft.datafixer.Schemas
import net.minecraft.datafixer.TypeReferences import net.minecraft.datafixer.TypeReferences
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.item.Items import net.minecraft.item.Items
import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtElement import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtHelper
import net.minecraft.nbt.NbtList
import net.minecraft.nbt.NbtOps import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.NbtString
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
import moe.nea.firmament.util.LegacyTagParser import moe.nea.firmament.util.LegacyTagParser
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.appendLore import moe.nea.firmament.util.appendLore
import moe.nea.firmament.util.getOrCreateList import moe.nea.firmament.util.item.setCustomName
import moe.nea.firmament.util.item.MinecraftProfileTextureKt import moe.nea.firmament.util.item.setSkullOwner
import moe.nea.firmament.util.item.MinecraftTexturesPayloadKt import moe.nea.firmament.util.modifyLore
import moe.nea.firmament.util.item.setTextures
import moe.nea.firmament.util.skyblockId import moe.nea.firmament.util.skyblockId
object ItemCache : IReloadable { object ItemCache : IReloadable {
@@ -90,10 +88,11 @@ object ItemCache : IReloadable {
val oldItemTag = get10809CompoundTag() val oldItemTag = get10809CompoundTag()
val modernItemTag = oldItemTag.transformFrom10809ToModern() val modernItemTag = oldItemTag.transformFrom10809ToModern()
?: return brokenItemStack(this) ?: return brokenItemStack(this)
val itemInstance = ItemStack.fromNbt(modernItemTag) val itemInstance =
if (itemInstance.nbt?.contains("Enchantments") == true) { ItemStack.fromNbt(MC.defaultRegistries, modernItemTag).getOrNull() ?: return brokenItemStack(this)
itemInstance.enchantments.add(NbtCompound()) val extraAttributes = oldItemTag.getCompound("tag").getCompound("ExtraAttributes")
} if (extraAttributes != null)
itemInstance.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraAttributes))
return itemInstance return itemInstance
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
@@ -117,19 +116,11 @@ object ItemCache : IReloadable {
} }
fun ItemStack.applyLoreReplacements(loreReplacements: Map<String, String>) { fun ItemStack.applyLoreReplacements(loreReplacements: Map<String, String>) {
val component = getOrCreateSubNbt("display") modifyLore { lore ->
val lore = component.getOrCreateList("Lore", NbtString.STRING_TYPE) lore.map {
val newLore = NbtList() it.applyLoreReplacements(loreReplacements)
lore.forEach { }
newLore.add(
NbtString.of(
Text.Serialization.toJsonString(
Text.Serialization.fromJson(it.asString())!!.applyLoreReplacements(loreReplacements)
)
)
)
} }
component["Lore"] = newLore
} }
fun Text.applyLoreReplacements(loreReplacements: Map<String, String>): Text { fun Text.applyLoreReplacements(loreReplacements: Map<String, String>): Text {
@@ -141,10 +132,8 @@ object ItemCache : IReloadable {
return Text.literal(string).styled { this.style } return Text.literal(string).styled { this.style }
} }
fun NEUItem.getIdentifier() = skyblockId.identifier fun NEUItem.getIdentifier() = skyblockId.identifier
var job: Job? = null var job: Job? = null
override fun reload(repository: NEURepository) { override fun reload(repository: NEURepository) {
@@ -189,21 +178,7 @@ object ItemCache : IReloadable {
} }
val itemStack = ItemStack(Items.PLAYER_HEAD) val itemStack = ItemStack(Items.PLAYER_HEAD)
itemStack.setCustomName(Text.literal("§r§6" + NumberFormat.getInstance().format(coinAmount) + " Coins")) itemStack.setCustomName(Text.literal("§r§6" + NumberFormat.getInstance().format(coinAmount) + " Coins"))
val nbt: NbtCompound = itemStack.orCreateNbt itemStack.setSkullOwner(uuid, texture)
nbt[SkullBlockEntity.SKULL_OWNER_KEY] = NbtHelper.writeGameProfile(
NbtCompound(),
GameProfile(uuid, "CoolGuy123").also {
it.setTextures(
MinecraftTexturesPayloadKt(
mapOf(
MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(texture),
),
uuid,
"CoolGuy123"
)
)
}
)
return itemStack return itemStack
} }
} }

View File

@@ -22,9 +22,12 @@ import net.minecraft.resource.InputSupplier
import net.minecraft.resource.NamespaceResourceManager import net.minecraft.resource.NamespaceResourceManager
import net.minecraft.resource.Resource import net.minecraft.resource.Resource
import net.minecraft.resource.ResourcePack import net.minecraft.resource.ResourcePack
import net.minecraft.resource.ResourcePackInfo
import net.minecraft.resource.ResourcePackSource
import net.minecraft.resource.ResourceType import net.minecraft.resource.ResourceType
import net.minecraft.resource.metadata.ResourceMetadata import net.minecraft.resource.metadata.ResourceMetadata
import net.minecraft.resource.metadata.ResourceMetadataReader import net.minecraft.resource.metadata.ResourceMetadataReader
import net.minecraft.text.Text
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.PathUtil import net.minecraft.util.PathUtil
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
@@ -113,12 +116,16 @@ class RepoModResourcePack(val basePath: Path) : ModResourcePack {
) )
} }
override fun getName(): String { override fun getInfo(): ResourcePackInfo {
return "NEU Repo Resources" return ResourcePackInfo("neurepo", Text.literal("NEU Repo"), ResourcePackSource.BUILTIN, Optional.empty())
} }
override fun getFabricModMetadata(): ModMetadata { override fun getFabricModMetadata(): ModMetadata {
return FabricLoader.getInstance().getModContainer("firmament") return FabricLoader.getInstance().getModContainer("firmament")
.get().metadata .get().metadata
} }
override fun createOverlay(overlay: String): ModResourcePack {
return RepoModResourcePack(basePath.resolve(overlay))
}
} }

View File

@@ -10,33 +10,22 @@ package moe.nea.firmament.util
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtList import net.minecraft.nbt.NbtList
import net.minecraft.nbt.NbtString
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.util.item.loreAccordingToNbt
fun ItemStack.appendLore(args: List<Text>) { fun ItemStack.appendLore(args: List<Text>) {
if (args.isEmpty()) return if (args.isEmpty()) return
val compoundTag = getOrCreateSubNbt("display") modifyLore {
val loreList = compoundTag.getOrCreateList("Lore", NbtString.STRING_TYPE) val loreList = loreAccordingToNbt.toMutableList()
for (arg in args) { for (arg in args) {
loreList.add(NbtString.of(Text.Serialization.toJsonString(arg))) loreList.add(arg)
}
loreList
} }
} }
fun ItemStack.modifyLore(update: (List<Text>) -> List<Text>) { fun ItemStack.modifyLore(update: (List<Text>) -> List<Text>) {
val compoundTag = getOrCreateSubNbt("display") val loreList = loreAccordingToNbt
val loreList = compoundTag.getOrCreateList("Lore", NbtString.STRING_TYPE) loreAccordingToNbt = update(loreList)
val parsed = loreList.map { Text.Serialization.fromJson(it.asString())!! }
val updated = update(parsed)
loreList.clear()
loreList.addAll(updated.map { NbtString.of(Text.Serialization.toJsonString(it)) })
}
fun NbtCompound.getOrCreateList(label: String, tag: Byte): NbtList = getList(label, tag.toInt()).also {
put(label, it)
}
fun NbtCompound.getOrCreateCompoundTag(label: String): NbtCompound = getCompound(label).also {
put(label, it)
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -7,13 +8,12 @@
package moe.nea.firmament.util package moe.nea.firmament.util
import io.github.moulberry.repo.data.Coordinate import io.github.moulberry.repo.data.Coordinate
import java.time.Instant
import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.ConcurrentLinkedQueue
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.screen.ingame.HandledScreen import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.network.message.ArgumentSignatureDataMap
import net.minecraft.network.message.LastSeenMessagesCollector.LastSeenMessages
import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket
import net.minecraft.registry.BuiltinRegistries
import net.minecraft.registry.RegistryWrapper
import net.minecraft.resource.ReloadableResourceManagerImpl import net.minecraft.resource.ReloadableResourceManagerImpl
import net.minecraft.text.Text import net.minecraft.text.Text
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
@@ -40,14 +40,9 @@ object MC {
fun sendServerCommand(command: String) { fun sendServerCommand(command: String) {
val nh = player?.networkHandler ?: return val nh = player?.networkHandler ?: return
val lastSeenMessages: LastSeenMessages = nh.lastSeenMessagesCollector.collect()
nh.sendPacket( nh.sendPacket(
CommandExecutionC2SPacket( CommandExecutionC2SPacket(
command, command,
Instant.now(),
0L,
ArgumentSignatureDataMap.EMPTY,
lastSeenMessages.update()
) )
) )
} }
@@ -77,6 +72,8 @@ object MC {
set(value) = MinecraftClient.getInstance().setScreen(value) set(value) = MinecraftClient.getInstance().setScreen(value)
inline val handledScreen: HandledScreen<*>? get() = MinecraftClient.getInstance().currentScreen as? HandledScreen<*> inline val handledScreen: HandledScreen<*>? get() = MinecraftClient.getInstance().currentScreen as? HandledScreen<*>
inline val window get() = MinecraftClient.getInstance().window inline val window get() = MinecraftClient.getInstance().window
inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager
val defaultRegistries: RegistryWrapper.WrapperLookup = BuiltinRegistries.createWrapperLookup()
} }

View File

@@ -16,6 +16,7 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import net.minecraft.component.DataComponentTypes
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtCompound
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
@@ -76,7 +77,7 @@ data class HypixelPetInfo(
private val jsonparser = Json { ignoreUnknownKeys = true } private val jsonparser = Json { ignoreUnknownKeys = true }
val ItemStack.extraAttributes: NbtCompound val ItemStack.extraAttributes: NbtCompound
get() = getOrCreateSubNbt("ExtraAttributes") get() = get(DataComponentTypes.CUSTOM_DATA)?.nbt ?: NbtCompound()
val ItemStack.skyblockUUIDString: String? val ItemStack.skyblockUUIDString: String?
get() = extraAttributes.getString("uuid")?.takeIf { it.isNotBlank() } get() = extraAttributes.getString("uuid")?.takeIf { it.isNotBlank() }
@@ -121,7 +122,7 @@ val ItemStack.skyBlockId: SkyblockId?
else SkyblockId("${enchantName.uppercase()};${enchantmentData.getInt(enchantName)}") else SkyblockId("${enchantName.uppercase()};${enchantmentData.getInt(enchantName)}")
} }
// TODO: PARTY_HAT_CRAB{,_ANIMATED,_SLOTH} // TODO: PARTY_HAT_CRAB{,_ANIMATED,_SLOTH},POTION
else -> { else -> {
SkyblockId(id) SkyblockId(id)
} }

View File

@@ -1,5 +1,6 @@
/* /*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
* SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -35,7 +36,6 @@ abstract class ProfileSpecificDataHolder<S>(
init { init {
allConfigs = readValues() allConfigs = readValues()
readValues()
IDataHolder.putDataHolder(this::class, this) IDataHolder.putDataHolder(this::class, this)
} }

View File

@@ -7,27 +7,20 @@
package moe.nea.firmament.util.item package moe.nea.firmament.util.item
import net.minecraft.component.DataComponentTypes
import net.minecraft.component.type.LoreComponent
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtString
import net.minecraft.text.Text import net.minecraft.text.Text
fun textFromNbt() { var ItemStack.loreAccordingToNbt
get() = get(DataComponentTypes.LORE)?.lines ?: listOf()
} set(value) {
set(DataComponentTypes.LORE, LoreComponent(value))
val ItemStack.loreAccordingToNbt
get() = getOrCreateSubNbt(ItemStack.DISPLAY_KEY).getList(ItemStack.LORE_KEY, NbtElement.STRING_TYPE.toInt())
.map {
lazy(LazyThreadSafetyMode.NONE) {
Text.Serialization.fromJson((it as NbtString).asString())
}
} }
val ItemStack.displayNameAccordingToNbt val ItemStack.displayNameAccordingToNbt
get() = getOrCreateSubNbt(ItemStack.DISPLAY_KEY).let { get() = get(DataComponentTypes.CUSTOM_NAME) ?: get(DataComponentTypes.ITEM_NAME) ?: item.name
if (it.contains(ItemStack.NAME_KEY, NbtElement.STRING_TYPE.toInt()))
Text.Serialization.fromJson(it.getString(ItemStack.NAME_KEY)) fun ItemStack.setCustomName(literal: Text) {
else set(DataComponentTypes.CUSTOM_NAME, literal)
null
} }

View File

@@ -17,15 +17,12 @@ import kotlinx.datetime.Clock
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import net.minecraft.block.entity.SkullBlockEntity import net.minecraft.component.DataComponentTypes
import net.minecraft.component.type.ProfileComponent
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.item.Items import net.minecraft.item.Items
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtHelper
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
import moe.nea.firmament.repo.set
import moe.nea.firmament.util.assertTrueOr import moe.nea.firmament.util.assertTrueOr
import moe.nea.firmament.util.json.DashlessUUIDSerializer import moe.nea.firmament.util.json.DashlessUUIDSerializer
import moe.nea.firmament.util.json.InstantAsLongSerializer import moe.nea.firmament.util.json.InstantAsLongSerializer
@@ -60,11 +57,7 @@ fun ItemStack.setEncodedSkullOwner(uuid: UUID, encodedData: String) {
assert(this.item == Items.PLAYER_HEAD) assert(this.item == Items.PLAYER_HEAD)
val gameProfile = GameProfile(uuid, "LameGuy123") val gameProfile = GameProfile(uuid, "LameGuy123")
gameProfile.properties.put(propertyTextures, Property(propertyTextures, encodedData.padBase64())) gameProfile.properties.put(propertyTextures, Property(propertyTextures, encodedData.padBase64()))
val nbt: NbtCompound = this.orCreateNbt this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile))
nbt[SkullBlockEntity.SKULL_OWNER_KEY] = NbtHelper.writeGameProfile(
NbtCompound(),
gameProfile
)
} }
val zeroUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1") val zeroUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1")
@@ -76,12 +69,7 @@ fun ItemStack.setSkullOwner(uuid: UUID, url: String) {
mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url)) mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url))
) )
) )
val nbt: NbtCompound = this.orCreateNbt this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile))
nbt[SkullBlockEntity.SKULL_OWNER_KEY] = NbtHelper.writeGameProfile(
NbtCompound(),
gameProfile
)
} }

View File

@@ -23,7 +23,6 @@ import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats import net.minecraft.client.render.VertexFormats
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.math.MatrixStack import net.minecraft.client.util.math.MatrixStack
import net.minecraft.client.util.math.MatrixStack.Entry
import net.minecraft.text.Text import net.minecraft.text.Text
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
@@ -166,7 +165,7 @@ class RenderInWorldContext private constructor(
companion object { companion object {
private fun doLine( private fun doLine(
matrix: Entry, matrix: MatrixStack.Entry,
buf: BufferBuilder, buf: BufferBuilder,
i: Number, i: Number,
j: Number, j: Number,
@@ -179,9 +178,9 @@ class RenderInWorldContext private constructor(
.sub(i.toFloat(), j.toFloat(), k.toFloat()) .sub(i.toFloat(), j.toFloat(), k.toFloat())
.normalize() .normalize()
buf.vertex(matrix.positionMatrix, i.toFloat(), j.toFloat(), k.toFloat()) buf.vertex(matrix.positionMatrix, i.toFloat(), j.toFloat(), k.toFloat())
.normal(matrix.normalMatrix, normal.x, normal.y, normal.z).next() .normal(matrix, normal.x, normal.y, normal.z).next()
buf.vertex(matrix.positionMatrix, x.toFloat(), y.toFloat(), z.toFloat()) buf.vertex(matrix.positionMatrix, x.toFloat(), y.toFloat(), z.toFloat())
.normal(matrix.normalMatrix, normal.x, normal.y, normal.z).next() .normal(matrix, normal.x, normal.y, normal.z).next()
} }