diff --git a/build.gradle b/build.gradle index 32b3a5b9..c9d11985 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,9 @@ plugins { } version = "$baseVersion+$branch" -archivesBaseName = project.slug +base { + archivesName = project.slug +} repositories { maven { url "https://maven.nucleoid.xyz/" } @@ -18,29 +20,40 @@ repositories { name = 'BlameJared Maven (CrT / Bookshelf)' url = 'https://maven.blamejared.com' } + exclusiveContent { + forRepository { + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + } + } + filter { + includeGroup "maven.modrinth" + } + } } dependencies { minecraft libs.mc - mappings variantOf(libs.yarn) { classifier "v2" } - - modImplementation libs.fl - modImplementation libs.fapi - modImplementation libs.placeholder - modCompileOnly libs.polydex + implementation libs.fl + implementation libs.fapi + implementation libs.placeholder include libs.placeholder - modLocalRuntime libs.polydex + +// compileOnly libs.polydex +// +// localRuntime libs.polydex implementation libs.kaleidoConfig include libs.kaleidoConfig - /*modCompileOnly libs.emi - modLocalRuntime libs.emi*/ + /*compileOnly libs.emi + localRuntime libs.emi*/ - modCompileOnly libs.modmenu - modLocalRuntime libs.modmenu + compileOnly libs.modmenu + localRuntime libs.modmenu } loom { @@ -54,29 +67,29 @@ loom { source sourceSets.main vmArg "-Dmixin.debug.export=true" - try { - afterEvaluate { - def mixinDep = this.configurations.compileClasspath - .allDependencies - .findAll { it.name == "sponge-mixin" } - .first() - - if (mixin != null) { - def mixinPath = this.configurations.compileClasspath.files(mixinDep).first().path; - - println(mixinPath) - - vmArg("-javaagent:\"${mixinPath}\"") - - println("[Info]: Mixin Hotswap Run should be working") - } else { - println("[Warning]: Unable to locate file path for Mixin Jar, HotSwap Run will not work!") - } - } - } catch (Exception e) { - println("[Error]: MixinHotswap Run had a issue!") - e.printStackTrace() - } +// try { +// afterEvaluate { +// def mixinDep = this.configurations.compileClasspath +// .allDependencies +// .findAll { it.name == "sponge-mixin" } +// .first() +// +// if (mixin != null) { +// def mixinPath = this.configurations.compileClasspath.files(mixinDep).first().path; +// +// println(mixinPath) +// +// vmArg("-javaagent:\"${mixinPath}\"") +// +// println("[Info]: Mixin Hotswap Run should be working") +// } else { +// println("[Warning]: Unable to locate file path for Mixin Jar, HotSwap Run will not work!") +// } +// } +// } catch (Exception e) { +// println("[Error]: MixinHotswap Run had a issue!") +// e.printStackTrace() +// } } } } @@ -104,7 +117,7 @@ processResources { fl : libs.versions.fl.get(), fapi : libs.versions.fapi.get(), placeholder : libs.versions.placeholder.get(), - polydex : libs.versions.polydex.get() +// polydex : libs.versions.polydex.get() ] inputs.properties meta filesMatching("*.mod.json") { expand(meta) } @@ -113,13 +126,13 @@ processResources { tasks.withType(JavaCompile).configureEach { it.options.encoding = "UTF-8" - it.options.release = 21 + it.options.release = 25 } java { withSourcesJar() - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 } jar { @@ -140,7 +153,7 @@ modrinth { token = "$System.env.MODRINTH_TOKEN" projectId = slug versionNumber = project.version - uploadFile = remapJar + uploadFile = jar gameVersions = compatibleVersions.split(", ").toList() loaders = compatibleLoaders.split(", ").toList() changelog = "$System.env.CHANGELOG" @@ -148,6 +161,6 @@ modrinth { dependencies { required.version "fabric-api", libs.versions.fapi.get() embedded.version "placeholder-api", libs.versions.placeholder.get() - optional.version "polydex", libs.versions.polydex.get() +// optional.version "polydex", libs.versions.polydex.get() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ff23a68d..37f78a6a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/libs.versions.toml b/libs.versions.toml index 4b05785b..2bd4926c 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -1,31 +1,30 @@ [versions] -loom = "1.11.+" +loom = "1.15-SNAPSHOT" minotaur = "2.+" kaleidoConfig = "0.3.3+1.3.2" -mc = "1.21.7" -fl = "0.16.14" -yarn = "1.21.7+build.2" -fapi = "0.128.2+1.21.7" +mc = "26.1-snapshot-9" +fl = "0.18.4" +fapi = "0.143.5+26.1" -placeholder = "2.4.0+1.21" -polydex = "1.6.0+1.21.6" +placeholder = "3.0.0-beta.1+26.1" +#polydex = "1.8.1+1.21.11" # emi = "1.1.19+1.21.1" -modmenu = "15.0.0-beta.3" +modmenu = "18.0.0-alpha.5" [plugins] -loom = { id = "fabric-loom", version.ref = "loom" } +loom = { id = "net.fabricmc.fabric-loom", version.ref = "loom" } minotaur = { id = "com.modrinth.minotaur", version.ref = "minotaur" } [libraries] mc = { group = "mojang", name = "minecraft", version.ref = "mc" } fl = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fl" } -yarn = { group = "net.fabricmc", name = "yarn", version.ref = "yarn" } fapi = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fapi" } -placeholder = { group = "eu.pb4", name = "placeholder-api", version.ref = "placeholder" } -polydex = { group = "eu.pb4", name = "polydex", version.ref = "polydex" } +#placeholder = { group = "eu.pb4", name = "placeholder-api", version.ref = "placeholder" } // not available on its maven? using Modrinth one: +placeholder = { group = "maven.modrinth", name = "placeholder-api", version.ref = "placeholder" } +#polydex = { group = "eu.pb4", name = "polydex", version.ref = "polydex" } kaleidoConfig = { group = "folk.sisby", name = "kaleido-config", version.ref = "kaleidoConfig" } # emi = { group = "dev.emi", name = "emi-fabric", version.ref = "emi" } diff --git a/src/main/java/dev/hephaestus/glowcase/Glowcase.java b/src/main/java/dev/hephaestus/glowcase/Glowcase.java index 63dd054a..4d149460 100644 --- a/src/main/java/dev/hephaestus/glowcase/Glowcase.java +++ b/src/main/java/dev/hephaestus/glowcase/Glowcase.java @@ -18,7 +18,7 @@ import dev.hephaestus.glowcase.block.entity.SoundPlayerBlockEntity; import dev.hephaestus.glowcase.block.entity.SpriteBlockEntity; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import dev.hephaestus.glowcase.compat.PolydexCompatibility; +//import dev.hephaestus.glowcase.compat.PolydexCompatibility; import dev.hephaestus.glowcase.item.CollectionCaseItem; import dev.hephaestus.glowcase.item.LockItem; import dev.hephaestus.glowcase.item.NoteItem; @@ -27,30 +27,30 @@ import dev.hephaestus.glowcase.item.component.NoteComponent; import dev.hephaestus.glowcase.item.component.TabletComponents; import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; +import net.fabricmc.fabric.api.creativetab.v1.FabricCreativeModeTab; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.component.ComponentType; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.DyedColorComponent; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemGroup; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.tag.TagKey; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.Identifier; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.DyedItemColor; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,7 +66,7 @@ public class Glowcase implements ModInitializer { public static final GlowcaseConfig CONFIG = GlowcaseConfig.createToml(FabricLoader.getInstance().getConfigDir(), "", MODID, GlowcaseConfig.class); public static GlowcaseCommonProxy proxy = new GlowcaseCommonProxy(); //Overridden in GlowcaseClient - public static final TagKey ITEM_TAG = TagKey.of(RegistryKeys.ITEM, id("items")); + public static final TagKey ITEM_TAG = TagKey.create(Registries.ITEM, id("items")); public static final Supplier HYPERLINK_BLOCK = registerBlock("hyperlink_block", HyperlinkBlock::new); public static final Supplier HYPERLINK_BLOCK_ITEM = registerBlockItem("hyperlink_block", HYPERLINK_BLOCK); @@ -122,72 +122,72 @@ public class Glowcase implements ModInitializer { public static final Supplier LOCK_ITEM = registerItem("lock", LockItem::new); - public static final Supplier> COLLECTION_COMPONENT = registerComponent("collection", () -> CollectionComponent.TYPE); - public static final Supplier COLLECTION_CASE_ITEM = registerItem("collection_case", (settings) -> new CollectionCaseItem(settings.component(COLLECTION_COMPONENT.get(), new CollectionComponent()).component(DataComponentTypes.DYED_COLOR, new DyedColorComponent(0xFFFFFF)))); + public static final Supplier> COLLECTION_COMPONENT = registerComponent("collection", () -> CollectionComponent.TYPE); + public static final Supplier COLLECTION_CASE_ITEM = registerItem("collection_case", (settings) -> new CollectionCaseItem(settings.component(COLLECTION_COMPONENT.get(), new CollectionComponent()).component(DataComponents.DYED_COLOR, new DyedItemColor(0xFFFFFF)))); public static final Supplier TABLET_ITEM = registerItem("tablet", TabletItem::new); - public static final Supplier>> LINKED_SCREEN_COMPONENT = registerComponent("linked_screen", () -> TabletComponents.LINKED_SCREEN_TYPE); - public static final Supplier> CURRENT_SLIDE_COMPONENT = registerComponent("current_slide", () -> TabletComponents.CURRENT_SLIDE_TYPE); - public static final Supplier>>> SLIDESHOW_COMPONENT = registerComponent("slideshow", () -> TabletComponents.SLIDESHOW_COMPONENT_TYPE); + public static final Supplier>> LINKED_SCREEN_COMPONENT = registerComponent("linked_screen", () -> TabletComponents.LINKED_SCREEN_TYPE); + public static final Supplier> CURRENT_SLIDE_COMPONENT = registerComponent("current_slide", () -> TabletComponents.CURRENT_SLIDE_TYPE); + public static final Supplier>>> SLIDESHOW_COMPONENT = registerComponent("slideshow", () -> TabletComponents.SLIDESHOW_COMPONENT_TYPE); public static final Supplier NOTE_ITEM = registerItem("note", NoteItem::new); - public static final Supplier> NOTE_COMPONENT = registerComponent("note", () -> NoteComponent.TYPE); + public static final Supplier> NOTE_COMPONENT = registerComponent("note", () -> NoteComponent.TYPE); public static final Supplier ENTITY_DISPLAY_BLOCK = registerBlock("entity_display_block", EntityDisplayBlock::new); public static final Supplier ENTITY_DISPLAY_BLOCK_ITEM = registerBlockItem("entity_display_block", ENTITY_DISPLAY_BLOCK); public static final Supplier> ENTITY_DISPLAY_BLOCK_ENTITY = registerBlockEntity("entity_display_block", () -> FabricBlockEntityTypeBuilder.create(EntityDisplayBlockEntity::new, ENTITY_DISPLAY_BLOCK.get()).build(null)); - public static final Supplier ITEM_GROUP = registerItemGroup("items", () -> FabricItemGroup.builder() - .displayName(Text.translatable("itemGroup.glowcase.items")) + public static final Supplier ITEM_GROUP = registerItemGroup("items", () -> FabricCreativeModeTab.builder() + .title(Component.translatable("itemGroup.glowcase.items")) .icon(() -> new ItemStack(SPRITE_BLOCK_ITEM.get())) - .entries((displayContext, entries) -> { - entries.add(TEXT_BLOCK_ITEM.get()); - entries.add(ENTITY_DISPLAY_BLOCK_ITEM.get()); - entries.add(ITEM_DISPLAY_BLOCK_ITEM.get()); - entries.add(RECIPE_BLOCK_ITEM.get()); - entries.add(SPRITE_BLOCK_ITEM.get()); - entries.add(PARTICLE_DISPLAY_ITEM.get()); - entries.add(SOUND_BLOCK_ITEM.get()); - entries.add(SCREEN_BLOCK_ITEM.get()); - entries.add(OUTLINE_BLOCK_ITEM.get()); - entries.add(HYPERLINK_BLOCK_ITEM.get()); - entries.add(CONFIG_LINK_BLOCK_ITEM.get()); - entries.add(POPUP_BLOCK_ITEM.get()); - entries.add(ITEM_PROVIDER_BLOCK_ITEM.get()); - entries.add(ITEM_ACCEPTOR_BLOCK_ITEM.get()); - entries.add(LOCK_ITEM.get()); - entries.add(COLLECTION_CASE_ITEM.get()); - entries.add(TABLET_ITEM.get()); - entries.add(NOTE_ITEM.get()); + .displayItems((displayContext, entries) -> { + entries.accept(TEXT_BLOCK_ITEM.get()); + entries.accept(ENTITY_DISPLAY_BLOCK_ITEM.get()); + entries.accept(ITEM_DISPLAY_BLOCK_ITEM.get()); + entries.accept(RECIPE_BLOCK_ITEM.get()); + entries.accept(SPRITE_BLOCK_ITEM.get()); + entries.accept(PARTICLE_DISPLAY_ITEM.get()); + entries.accept(SOUND_BLOCK_ITEM.get()); + entries.accept(SCREEN_BLOCK_ITEM.get()); + entries.accept(OUTLINE_BLOCK_ITEM.get()); + entries.accept(HYPERLINK_BLOCK_ITEM.get()); + entries.accept(CONFIG_LINK_BLOCK_ITEM.get()); + entries.accept(POPUP_BLOCK_ITEM.get()); + entries.accept(ITEM_PROVIDER_BLOCK_ITEM.get()); + entries.accept(ITEM_ACCEPTOR_BLOCK_ITEM.get()); + entries.accept(LOCK_ITEM.get()); + entries.accept(COLLECTION_CASE_ITEM.get()); + entries.accept(TABLET_ITEM.get()); + entries.accept(NOTE_ITEM.get()); }) .build() ); public static Identifier id(String... path) { - return Identifier.of(MODID, String.join("/", path)); + return Identifier.fromNamespaceAndPath(MODID, String.join("/", path)); } - public static Supplier registerBlock(String path, Function supplier) { + public static Supplier registerBlock(String path, Function supplier) { Identifier identifier = id(path); - AbstractBlock.Settings settings = GlowcaseBlock.defaultSettings().registryKey(RegistryKey.of(RegistryKeys.BLOCK, identifier)); + BlockBehaviour.Properties settings = GlowcaseBlock.defaultSettings().setId(ResourceKey.create(Registries.BLOCK, identifier)); - return Suppliers.ofInstance(Registry.register(Registries.BLOCK, identifier, supplier.apply(settings))); + return Suppliers.ofInstance(Registry.register(BuiltInRegistries.BLOCK, identifier, supplier.apply(settings))); } public static Supplier registerBlockItem(String path, Supplier block) { return registerBlockItem(path, block, settings -> {}); } - public static Supplier registerBlockItem(String path, Supplier blockSupplier, Consumer seetingsConsumer) { + public static Supplier registerBlockItem(String path, Supplier blockSupplier, Consumer seetingsConsumer) { Identifier identifier = id(path); Block block = blockSupplier.get(); - Item.Settings settings = defaultItemSettings().registryKey(RegistryKey.of(RegistryKeys.ITEM, identifier)); + Item.Properties settings = defaultItemSettings().setId(ResourceKey.create(Registries.ITEM, identifier)); seetingsConsumer.accept(settings); BlockItem blockItem; if (block instanceof GlowcaseBlock glowcaseBlock) { blockItem = new BlockItem(block, settings) { @Override - public void appendTooltip(ItemStack stack, TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { + public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { glowcaseBlock.appendTooltip(stack, context, displayComponent, textConsumer, type); } }; @@ -195,39 +195,39 @@ public void appendTooltip(ItemStack stack, TooltipContext context, TooltipDispla blockItem = new BlockItem(block, settings); } - return Suppliers.ofInstance(Registry.register(Registries.ITEM, identifier, blockItem)); + return Suppliers.ofInstance(Registry.register(BuiltInRegistries.ITEM, identifier, blockItem)); } - public static Supplier registerItem(String path, Function supplier) { + public static Supplier registerItem(String path, Function supplier) { Identifier identifier = id(path); - Item.Settings settings = defaultItemSettings().registryKey(RegistryKey.of(RegistryKeys.ITEM, identifier)); + Item.Properties settings = defaultItemSettings().setId(ResourceKey.create(Registries.ITEM, identifier)); - return Suppliers.ofInstance(Registry.register(Registries.ITEM, identifier, supplier.apply(settings))); + return Suppliers.ofInstance(Registry.register(BuiltInRegistries.ITEM, identifier, supplier.apply(settings))); } - public static , U> Supplier registerComponent(String path, Supplier supplier) { - return Suppliers.ofInstance(Registry.register(Registries.DATA_COMPONENT_TYPE, id(path), supplier.get())); + public static , U> Supplier registerComponent(String path, Supplier supplier) { + return Suppliers.ofInstance(Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, id(path), supplier.get())); } - public static Supplier registerItemGroup(String path, Supplier supplier) { - return Suppliers.ofInstance(Registry.register(Registries.ITEM_GROUP, id(path), supplier.get())); + public static Supplier registerItemGroup(String path, Supplier supplier) { + return Suppliers.ofInstance(Registry.register(BuiltInRegistries.CREATIVE_MODE_TAB, id(path), supplier.get())); } public static Supplier> registerBlockEntity(String path, Supplier> supplier) { - return Suppliers.ofInstance(Registry.register(Registries.BLOCK_ENTITY_TYPE, id(path), supplier.get())); + return Suppliers.ofInstance(Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, id(path), supplier.get())); } - private static Item.Settings defaultItemSettings() { - return new Item.Settings().maxCount(1); + private static Item.Properties defaultItemSettings() { + return new Item.Properties().stacksTo(1); } @Override public void onInitialize() { GlowcaseNetworking.init(); - if (FabricLoader.getInstance().isModLoaded("polydex2")) { - PolydexCompatibility.onInitialize(); - } +// if (FabricLoader.getInstance().isModLoaded("polydex2")) { +// PolydexCompatibility.onInitialize(); +// } // Never make this command available outside of dev /*if (FabricLoader.getInstance().isDevelopmentEnvironment()) { diff --git a/src/main/java/dev/hephaestus/glowcase/GlowcaseCommonProxy.java b/src/main/java/dev/hephaestus/glowcase/GlowcaseCommonProxy.java index e887e366..c8a7b228 100644 --- a/src/main/java/dev/hephaestus/glowcase/GlowcaseCommonProxy.java +++ b/src/main/java/dev/hephaestus/glowcase/GlowcaseCommonProxy.java @@ -1,7 +1,7 @@ package dev.hephaestus.glowcase; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; public class GlowcaseCommonProxy { diff --git a/src/main/java/dev/hephaestus/glowcase/GlowcaseNetworking.java b/src/main/java/dev/hephaestus/glowcase/GlowcaseNetworking.java index 770cb7d7..11fb5098 100644 --- a/src/main/java/dev/hephaestus/glowcase/GlowcaseNetworking.java +++ b/src/main/java/dev/hephaestus/glowcase/GlowcaseNetworking.java @@ -20,30 +20,30 @@ import dev.hephaestus.glowcase.packet.C2SSlotScrolled; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.ScreenHandler; -import net.minecraft.screen.slot.Slot; -import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; public class GlowcaseNetworking { public static void init() { - PayloadTypeRegistry.playC2S().register(C2SEditHyperlinkBlock.ID, C2SEditHyperlinkBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditConfigLinkBlock.ID, C2SEditConfigLinkBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditItemDisplayBlock.ID, C2SEditItemDisplayBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditTextBlock.ID, C2SEditTextBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditPopupBlock.ID, C2SEditPopupBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditRecipeBlock.ID, C2SEditRecipeBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditSpriteBlock.ID, C2SEditSpriteBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditOutlineBlock.ID, C2SEditOutlineBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditParticleDisplayBlock.ID, C2SEditParticleDisplayBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditSoundBlock.ID, C2SEditSoundBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditItemAcceptorBlock.ID, C2SEditItemAcceptorBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditScreenBlock.ID, C2SEditScreenBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditItemProviderBlock.ID, C2SEditItemProviderBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditTabletItem.ID, C2SEditTabletItem.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditNoteItem.ID, C2SEditNoteItem.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SEditEntityDisplayBlock.ID, C2SEditEntityDisplayBlock.PACKET_CODEC); - PayloadTypeRegistry.playC2S().register(C2SSlotScrolled.ID, C2SSlotScrolled.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditHyperlinkBlock.ID, C2SEditHyperlinkBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditConfigLinkBlock.ID, C2SEditConfigLinkBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditItemDisplayBlock.ID, C2SEditItemDisplayBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditTextBlock.ID, C2SEditTextBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditPopupBlock.ID, C2SEditPopupBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditRecipeBlock.ID, C2SEditRecipeBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditSpriteBlock.ID, C2SEditSpriteBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditOutlineBlock.ID, C2SEditOutlineBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditParticleDisplayBlock.ID, C2SEditParticleDisplayBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditSoundBlock.ID, C2SEditSoundBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditItemAcceptorBlock.ID, C2SEditItemAcceptorBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditScreenBlock.ID, C2SEditScreenBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditItemProviderBlock.ID, C2SEditItemProviderBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditTabletItem.ID, C2SEditTabletItem.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditNoteItem.ID, C2SEditNoteItem.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SEditEntityDisplayBlock.ID, C2SEditEntityDisplayBlock.PACKET_CODEC); + PayloadTypeRegistry.serverboundPlay().register(C2SSlotScrolled.ID, C2SSlotScrolled.PACKET_CODEC); ServerPlayNetworking.registerGlobalReceiver(C2SEditHyperlinkBlock.ID, C2SEditHyperlinkBlock::receive); ServerPlayNetworking.registerGlobalReceiver(C2SEditConfigLinkBlock.ID, C2SEditConfigLinkBlock::receive); @@ -69,37 +69,37 @@ public static void init() { */ private static void slotScrolled(C2SSlotScrolled packet, ServerPlayNetworking.Context ctx) { ctx.server().execute(() -> { - ServerPlayerEntity player = ctx.player(); - player.updateLastActionTime(); - ScreenHandler screenHandler = player.currentScreenHandler; + ServerPlayer player = ctx.player(); + player.resetLastActionTime(); + AbstractContainerMenu screenHandler = player.containerMenu; - if (screenHandler.syncId != packet.syncId()) { + if (screenHandler.containerId != packet.syncId()) { return; } if (player.isSpectator()) { - screenHandler.syncState(); + screenHandler.sendAllDataToRemote(); return; } - if (!screenHandler.canUse(player)) { + if (!screenHandler.stillValid(player)) { Glowcase.LOGGER.debug("Player {} interacted with invalid menu {}", player, screenHandler); return; } - if (!screenHandler.isValid(packet.slotIndex())) { + if (!screenHandler.isValidSlotIndex(packet.slotIndex())) { Glowcase.LOGGER.debug("Player {} clicked invalid slot index: {}, available slots: {}", player.getName(), packet.slotIndex(), screenHandler.slots.size()); return; } - boolean flag = packet.revision() == player.currentScreenHandler.getRevision(); - screenHandler.disableSyncing(); + boolean flag = packet.revision() == player.containerMenu.getStateId(); + screenHandler.suppressRemoteUpdates(); Slot slot = screenHandler.getSlot(packet.slotIndex()); - ItemStack stack = slot.getStack(); + ItemStack stack = slot.getItem(); if (stack.getItem() instanceof ScrollableItem si) { si.scroll(stack, player, packet.amount()); } - screenHandler.enableSyncing(); + screenHandler.resumeRemoteUpdates(); if (flag) { - screenHandler.updateToClient(); + screenHandler.broadcastFullState(); } else { - screenHandler.sendContentUpdates(); + screenHandler.broadcastChanges(); } }); } diff --git a/src/main/java/dev/hephaestus/glowcase/block/ConfigLinkBlock.java b/src/main/java/dev/hephaestus/glowcase/block/ConfigLinkBlock.java index 23d5a24b..296dddfe 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/ConfigLinkBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/ConfigLinkBlock.java @@ -3,38 +3,38 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ConfigLinkBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; public class ConfigLinkBlock extends WaterloggableGlowcaseBlock { - public static final MapCodec CODEC = createCodec(ConfigLinkBlock::new); + public static final MapCodec CODEC = simpleCodec(ConfigLinkBlock::new); - public ConfigLinkBlock(AbstractBlock.Settings settings) { + public ConfigLinkBlock(BlockBehaviour.Properties settings) { super(settings); } @Override - protected VoxelShape targetedOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + protected VoxelShape targetedOutlineShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return HALF_CUBED; } @@ -45,33 +45,33 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - boolean canTarget(PlayerEntity player, BlockPos pos) { + boolean canTarget(Player player, BlockPos pos) { return true; } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new ConfigLinkBlockEntity(pos, state); } @Override - protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { - if (!(world.getBlockEntity(pos) instanceof ConfigLinkBlockEntity be)) return ActionResult.CONSUME; - if (world.isClient) { + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof ConfigLinkBlockEntity be)) return InteractionResult.CONSUME; + if (world.isClientSide()) { Glowcase.proxy.openConfigScreen(be.getUrl()); } - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.config_link_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.config_link_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/EntityDisplayBlock.java b/src/main/java/dev/hephaestus/glowcase/block/EntityDisplayBlock.java index bf599f25..9e26ed90 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/EntityDisplayBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/EntityDisplayBlock.java @@ -5,45 +5,45 @@ import dev.hephaestus.glowcase.block.entity.DisplayBlockEntity; import dev.hephaestus.glowcase.block.entity.EntityDisplayBlockEntity; import dev.hephaestus.glowcase.block.entity.StackInteractable; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityTicker; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.SpawnEggItem; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.SpawnEggItem; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; public class EntityDisplayBlock extends StackInteractableBlock { - public static final MapCodec CODEC = createCodec(EntityDisplayBlock::new); + public static final MapCodec CODEC = simpleCodec(EntityDisplayBlock::new); - public EntityDisplayBlock(AbstractBlock.Settings settings) { + public EntityDisplayBlock(BlockBehaviour.Properties settings) { super(settings); } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new EntityDisplayBlockEntity(pos, state); } @Override - public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { - super.onPlaced(world, pos, state, placer, itemStack); + public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { + super.setPlacedBy(world, pos, state, placer, itemStack); if (placer != null && world.getBlockEntity(pos) instanceof DisplayBlockEntity be) { - be.setYaw((Math.round(((540.0F - placer.getHeadYaw())) / 45.0F) * 45) % 360); + be.setYaw((Math.round(((540.0F - placer.getYHeadRot())) / 45.0F) * 45) % 360); } } @@ -54,26 +54,26 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - boolean canTarget(PlayerEntity player, BlockPos pos) { - if (!(player.getWorld().getBlockEntity(pos) instanceof StackInteractable be)) return false; - return canEditGlowcase(player, pos) && ((be.matchesStack(ItemStack.EMPTY) && player.getMainHandStack().getItem() instanceof SpawnEggItem) || be.matchesStack(player.getMainHandStack()) || player.getMainHandStack().isIn(Glowcase.ITEM_TAG)); + boolean canTarget(Player player, BlockPos pos) { + if (!(player.level().getBlockEntity(pos) instanceof StackInteractable be)) return false; + return canEditGlowcase(player, pos) && ((be.matchesStack(ItemStack.EMPTY) && player.getMainHandItem().getItem() instanceof SpawnEggItem) || be.matchesStack(player.getMainHandItem()) || player.getMainHandItem().is(Glowcase.ITEM_TAG)); } @Nullable @Override - public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { return checkType(type, Glowcase.ENTITY_DISPLAY_BLOCK_ENTITY.get(), EntityDisplayBlockEntity::tick); } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.entity_display_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.entity_display_block.tooltip.1").formatted(Formatting.DARK_GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.entity_display_block.tooltip.2").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.entity_display_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.entity_display_block.tooltip.1").withStyle(ChatFormatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.entity_display_block.tooltip.2").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/GlowcaseBlock.java b/src/main/java/dev/hephaestus/glowcase/block/GlowcaseBlock.java index 1cd7d417..0fd0b7f4 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/GlowcaseBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/GlowcaseBlock.java @@ -2,101 +2,102 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.GlowcaseBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.EntityShapeContext; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityTicker; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.NbtComponent; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; +import net.minecraft.world.item.component.TypedEntityData; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; - -public abstract class GlowcaseBlock extends BlockWithEntity { - protected static final VoxelShape HALF_CUBED = VoxelShapes.cuboid(0.25, 0.25, 0.25, 0.75, 0.75, 0.75); - - public GlowcaseBlock(AbstractBlock.Settings settings) { +import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.EntityCollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +public abstract class GlowcaseBlock extends BaseEntityBlock { + protected static final VoxelShape HALF_CUBED = Shapes.box(0.25, 0.25, 0.25, 0.75, 0.75, 0.75); + + public GlowcaseBlock(BlockBehaviour.Properties settings) { super(settings); } - boolean canTarget(PlayerEntity player, BlockPos pos) { - return canEditGlowcase(player, pos) && player.getMainHandStack().isIn(Glowcase.ITEM_TAG); + boolean canTarget(Player player, BlockPos pos) { + return canEditGlowcase(player, pos) && player.getMainHandItem().is(Glowcase.ITEM_TAG); } - protected VoxelShape targetedOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return VoxelShapes.fullCube(); + protected VoxelShape targetedOutlineShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + return Shapes.block(); } abstract protected boolean openEditScreen(BlockPos pos); - protected void loadClientSideNBT(World world, BlockPos pos, LivingEntity placer, ItemStack stack) { - if (world.isClient && placer instanceof PlayerEntity player && canEditGlowcase(player, pos)) { - NbtComponent blockEntityTag = stack.get(DataComponentTypes.BLOCK_ENTITY_DATA); + protected void loadClientSideNBT(Level world, BlockPos pos, LivingEntity placer, ItemStack stack) { + if (world.isClientSide() && placer instanceof Player player && canEditGlowcase(player, pos)) { + TypedEntityData> blockEntityTag = stack.get(DataComponents.BLOCK_ENTITY_DATA); if (blockEntityTag != null && world.getBlockEntity(pos) instanceof BlockEntity be) { - blockEntityTag.applyToBlockEntity(be, world.getRegistryManager()); + blockEntityTag.loadInto(be, world.registryAccess()); } openEditScreen(pos); } } @Override - public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { + public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { loadClientSideNBT(world, pos, placer, stack); - if (world.isClient && placer instanceof PlayerEntity player && canEditGlowcase(player, pos)) { + if (world.isClientSide() && placer instanceof Player player && canEditGlowcase(player, pos)) { openEditScreen(pos); } } @Override - protected ActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { if (!(world.getBlockEntity(pos) instanceof GlowcaseBlockEntity)) { - return ActionResult.PASS_TO_DEFAULT_BLOCK_ACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } - if (player.getStackInHand(hand).isIn(Glowcase.ITEM_TAG) && canEditGlowcase(player, pos)) { - if (world.isClient) { + if (player.getItemInHand(hand).is(Glowcase.ITEM_TAG) && canEditGlowcase(player, pos)) { + if (world.isClientSide()) { openEditScreen(pos); } - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } - return ActionResult.PASS_TO_DEFAULT_BLOCK_ACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } @Override - public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - if (context != ShapeContext.absent() && context instanceof EntityShapeContext esc && esc.getEntity() instanceof PlayerEntity player && canTarget(player, pos) + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + if (context != CollisionContext.empty() && context instanceof EntityCollisionContext esc && esc.getEntity() instanceof Player player && canTarget(player, pos) ) { return targetedOutlineShape(state, world, pos, context); } else { - return VoxelShapes.empty(); + return Shapes.empty(); } } @Override - public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return VoxelShapes.empty(); + public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + return Shapes.empty(); } @Nullable @@ -108,9 +109,9 @@ protected static BlockEntityTicke public static boolean canEditGlowcase(@Nullable LivingEntity entity, BlockPos pos) { if (entity == null) return false; - if (entity instanceof PlayerEntity player) { - if (player.getWorld() instanceof ServerWorld serverWorld) { - return player.isCreative() && player.canModifyAt(serverWorld, pos); + if (entity instanceof Player player) { + if (player.level() instanceof ServerLevel serverWorld) { + return player.isCreative() && player.mayInteract(serverWorld, pos); } return player.isCreative(); @@ -120,14 +121,14 @@ public static boolean canEditGlowcase(@Nullable LivingEntity entity, BlockPos po } @Deprecated - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { } - public static AbstractBlock.Settings defaultSettings() { - return Settings.create() - .nonOpaque() - .dropsNothing() - .noBlockBreakParticles() + public static BlockBehaviour.Properties defaultSettings() { + return Properties.of() + .noOcclusion() + .noLootTable() + .noTerrainParticles() .strength(-1, Float.MAX_VALUE); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/HyperlinkBlock.java b/src/main/java/dev/hephaestus/glowcase/block/HyperlinkBlock.java index d11ff59c..2670b61c 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/HyperlinkBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/HyperlinkBlock.java @@ -3,36 +3,38 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; -import net.minecraft.block.*; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; public class HyperlinkBlock extends WaterloggableGlowcaseBlock { - public static final MapCodec CODEC = createCodec(HyperlinkBlock::new); + public static final MapCodec CODEC = simpleCodec(HyperlinkBlock::new); - public HyperlinkBlock(AbstractBlock.Settings settings) { + public HyperlinkBlock(BlockBehaviour.Properties settings) { super(settings); } @Override - protected VoxelShape targetedOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + protected VoxelShape targetedOutlineShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return HALF_CUBED; } @@ -43,33 +45,33 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - boolean canTarget(PlayerEntity player, BlockPos pos) { + boolean canTarget(Player player, BlockPos pos) { return true; } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new HyperlinkBlockEntity(pos, state); } @Override - protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { - if (!(world.getBlockEntity(pos) instanceof HyperlinkBlockEntity be)) return ActionResult.CONSUME; - if (world.isClient && !be.getUrl().isBlank()) { + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof HyperlinkBlockEntity be)) return InteractionResult.CONSUME; + if (world.isClientSide() && !be.getUrl().isBlank()) { Glowcase.proxy.openUrlWithConfirmation(be.getUrl()); } - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.hyperlink_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.hyperlink_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/ItemAcceptorBlock.java b/src/main/java/dev/hephaestus/glowcase/block/ItemAcceptorBlock.java index 57f46978..3d469c5c 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/ItemAcceptorBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/ItemAcceptorBlock.java @@ -3,71 +3,71 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ItemAcceptorBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockRenderType; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.ChestBlock; -import net.minecraft.block.InventoryProvider; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.ChestBlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.Inventory; -import net.minecraft.item.Item; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.BooleanProperty; -import net.minecraft.state.property.EnumProperty; -import net.minecraft.state.property.Properties; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.random.Random; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; -import net.minecraft.world.block.OrientationHelper; -import net.minecraft.world.block.WireOrientation; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.Container; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.WorldlyContainerHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.ChestBlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils; +import net.minecraft.world.level.redstone.Orientation; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; public class ItemAcceptorBlock extends GlowcaseBlock { - public static final MapCodec CODEC = createCodec(ItemAcceptorBlock::new); - private static final VoxelShape OUTLINE = VoxelShapes.fullCube(); - public static final EnumProperty FACING = Properties.HORIZONTAL_FACING; - public static final BooleanProperty POWERED = Properties.POWERED; + public static final MapCodec CODEC = simpleCodec(ItemAcceptorBlock::new); + private static final VoxelShape OUTLINE = Shapes.block(); + public static final EnumProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final BooleanProperty POWERED = BlockStateProperties.POWERED; - public ItemAcceptorBlock(AbstractBlock.Settings settings) { + public ItemAcceptorBlock(BlockBehaviour.Properties settings) { super(settings); - this.setDefaultState(this.getDefaultState().with(FACING, Direction.NORTH).with(POWERED, false)); + this.registerDefaultState(this.defaultBlockState().setValue(FACING, Direction.NORTH).setValue(POWERED, false)); } @Override - protected BlockRenderType getRenderType(final BlockState state) { - return BlockRenderType.MODEL; + protected RenderShape getRenderShape(final BlockState state) { + return RenderShape.MODEL; } @Override - protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder); + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); builder.add(FACING, POWERED); } @Override - public BlockState getPlacementState(ItemPlacementContext ctx) { - return this.getDefaultState().with(FACING, ctx.getHorizontalPlayerFacing().getOpposite()); + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + return this.defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite()); } @Override @@ -77,56 +77,56 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { - if (!(world.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity be)) return ActionResult.CONSUME; + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity be)) return InteractionResult.CONSUME; if (canEditGlowcase(player, pos)) { - if (world.isClient) { + if (world.isClientSide()) { openEditScreen(pos); } - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } - return ActionResult.PASS; + return InteractionResult.PASS; } @Override - protected ActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { if (!(world.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity be)) { - return ActionResult.CONSUME; + return InteractionResult.CONSUME; } if (!be.isItemAccepted(stack)) { - return ActionResult.PASS_TO_DEFAULT_BLOCK_ACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } - if (world.getBlockTickScheduler().isQueued(pos, this) || state.get(POWERED)) { - return ActionResult.PASS; + if (world.getBlockTicks().hasScheduledTick(pos, this) || state.getValue(POWERED)) { + return InteractionResult.PASS; } - if (!world.isClient()) { + if (!world.isClientSide()) { // Remove items ItemStack newStack = stack.copyWithCount(be.count); - stack.decrementUnlessCreative(be.count, player); + stack.consume(be.count, player); // Attempt to insert items - if (getInventoryAt(world, pos.offset(getOutputDirection(world, pos, state))) instanceof Inventory inventory) { + if (getInventoryAt(world, pos.relative(getOutputDirection(world, pos, state))) instanceof Container inventory) { addToFirstFreeSlot(inventory, newStack); } // Schedule redstone pulse - if(be.getPulse() > 0) world.scheduleBlockTick(pos, this, 2); + if(be.getPulse() > 0) world.scheduleTick(pos, this, 2); } - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } - private static Inventory getInventoryAt(World world, BlockPos pos) { + private static Container getInventoryAt(Level world, BlockPos pos) { BlockState state = world.getBlockState(pos); Block block = state.getBlock(); - if (block instanceof InventoryProvider inventoryProvider) { - return inventoryProvider.getInventory(state, world, pos); - } else if (state.hasBlockEntity() && world.getBlockEntity(pos) instanceof Inventory inventory) { + if (block instanceof WorldlyContainerHolder inventoryProvider) { + return inventoryProvider.getContainer(state, world, pos); + } else if (state.hasBlockEntity() && world.getBlockEntity(pos) instanceof Container inventory) { if (inventory instanceof ChestBlockEntity && block instanceof ChestBlock chestBlock) { - return ChestBlock.getInventory(chestBlock, state, world, pos, true); + return ChestBlock.getContainer(chestBlock, state, world, pos, true); } return inventory; @@ -135,19 +135,19 @@ private static Inventory getInventoryAt(World world, BlockPos pos) { return null; } - private ItemStack addToFirstFreeSlot(Inventory inventory, ItemStack stack) { - int i = inventory.getMaxCount(stack); + private ItemStack addToFirstFreeSlot(Container inventory, ItemStack stack) { + int i = inventory.getMaxStackSize(stack); - for (int j = 0; j < inventory.size(); j++) { - ItemStack itemStack = inventory.getStack(j); - if (itemStack.isEmpty() || ItemStack.areItemsAndComponentsEqual(stack, itemStack)) { + for (int j = 0; j < inventory.getContainerSize(); j++) { + ItemStack itemStack = inventory.getItem(j); + if (itemStack.isEmpty() || ItemStack.isSameItemSameComponents(stack, itemStack)) { int k = Math.min(stack.getCount(), i - itemStack.getCount()); if (k > 0) { if (itemStack.isEmpty()) { - inventory.setStack(j, stack.split(k)); + inventory.setItem(j, stack.split(k)); } else { - stack.decrement(k); - itemStack.increment(k); + stack.shrink(k); + itemStack.grow(k); } } @@ -161,73 +161,73 @@ private ItemStack addToFirstFreeSlot(Inventory inventory, ItemStack stack) { } @Override - protected void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { - if (state.get(POWERED)) { - world.setBlockState(pos, state.with(POWERED, false), Block.NOTIFY_LISTENERS); + protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (state.getValue(POWERED)) { + world.setBlock(pos, state.setValue(POWERED, false), Block.UPDATE_CLIENTS); } else { - world.setBlockState(pos, state.with(POWERED, true), Block.NOTIFY_LISTENERS); - world.scheduleBlockTick(pos, this, world.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity be ? be.getPulse() : 4); + world.setBlock(pos, state.setValue(POWERED, true), Block.UPDATE_CLIENTS); + world.scheduleTick(pos, this, world.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity be ? be.getPulse() : 4); } this.updateNeighbors(world, pos, state); } - protected void updateNeighbors(World world, BlockPos pos, BlockState state) { + protected void updateNeighbors(Level world, BlockPos pos, BlockState state) { Direction direction = getOutputDirection(world, pos, state); - BlockPos blockPos = pos.offset(direction); - WireOrientation emissionOrientation = OrientationHelper.getEmissionOrientation(world, direction, null); - world.updateNeighbor(blockPos, this, emissionOrientation); - world.updateNeighborsExcept(blockPos, this, direction.getOpposite(), emissionOrientation); + BlockPos blockPos = pos.relative(direction); + Orientation emissionOrientation = ExperimentalRedstoneUtils.initialOrientation(world, direction, null); + world.neighborChanged(blockPos, this, emissionOrientation); + world.updateNeighborsAtExceptFromFacing(blockPos, this, direction.getOpposite(), emissionOrientation); } @Override - protected boolean emitsRedstonePower(BlockState state) { + protected boolean isSignalSource(BlockState state) { return true; } @Override - protected int getWeakRedstonePower(BlockState state, BlockView world, BlockPos pos, Direction direction) { - return state.get(POWERED) && getOutputDirection(world, pos, state) == direction.getOpposite() ? 15 : 0; + protected int getSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) { + return state.getValue(POWERED) && getOutputDirection(world, pos, state) == direction.getOpposite() ? 15 : 0; } - public Direction getOutputDirection(BlockView world, BlockPos pos, BlockState state) { + public Direction getOutputDirection(BlockGetter world, BlockPos pos, BlockState state) { if (world.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity blockEntity) { return switch (blockEntity.outputDirection) { case BOTTOM -> Direction.DOWN; - case BACK -> state.get(FACING).getOpposite(); + case BACK -> state.getValue(FACING).getOpposite(); case TOP -> Direction.UP; }; } - return state.get(FACING).getOpposite(); + return state.getValue(FACING).getOpposite(); } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new ItemAcceptorBlockEntity(pos, state); } @Override - public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return OUTLINE; } @Override - public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return OUTLINE; } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.item_acceptor_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.item_acceptor_block.tooltip.1").formatted(Formatting.BLUE)); - textConsumer.accept(Text.translatable("block.glowcase.item_acceptor_block.tooltip.2").formatted(Formatting.BLUE)); - textConsumer.accept(Text.translatable("block.glowcase.item_acceptor_block.tooltip.3").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.item_acceptor_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.item_acceptor_block.tooltip.1").withStyle(ChatFormatting.BLUE)); + textConsumer.accept(Component.translatable("block.glowcase.item_acceptor_block.tooltip.2").withStyle(ChatFormatting.BLUE)); + textConsumer.accept(Component.translatable("block.glowcase.item_acceptor_block.tooltip.3").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/ItemDisplayBlock.java b/src/main/java/dev/hephaestus/glowcase/block/ItemDisplayBlock.java index b188c914..e94106b3 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/ItemDisplayBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/ItemDisplayBlock.java @@ -4,28 +4,28 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.DisplayBlockEntity; import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; public class ItemDisplayBlock extends StackInteractableBlock { - public static final MapCodec CODEC = createCodec(ItemDisplayBlock::new); + public static final MapCodec CODEC = simpleCodec(ItemDisplayBlock::new); - public ItemDisplayBlock(AbstractBlock.Settings settings) { + public ItemDisplayBlock(BlockBehaviour.Properties settings) { super(settings); } @@ -37,27 +37,27 @@ protected boolean openEditScreen(BlockPos pos) { @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new ItemDisplayBlockEntity(pos, state); } @Override - public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { - super.onPlaced(world, pos, state, placer, itemStack); + public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { + super.setPlacedBy(world, pos, state, placer, itemStack); if (placer != null && world.getBlockEntity(pos) instanceof DisplayBlockEntity be) { - be.setYaw((Math.round(((540.0F - placer.getHeadYaw())) / 45.0F) * 45) % 360); + be.setYaw((Math.round(((540.0F - placer.getYHeadRot())) / 45.0F) * 45) % 360); } } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.item_display_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.item_display_block.tooltip.1").formatted(Formatting.DARK_GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.item_display_block.tooltip.2").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.item_display_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.item_display_block.tooltip.1").withStyle(ChatFormatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.item_display_block.tooltip.2").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/ItemProviderBlock.java b/src/main/java/dev/hephaestus/glowcase/block/ItemProviderBlock.java index 5c7d0a7d..0baf8cb0 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/ItemProviderBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/ItemProviderBlock.java @@ -3,70 +3,70 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ItemProviderBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.EnumProperty; -import net.minecraft.state.property.Properties; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3i; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; public class ItemProviderBlock extends StackInteractableBlock { - public static final MapCodec CODEC = createCodec(ItemProviderBlock::new); - public static final EnumProperty FACING = Properties.FACING; + public static final MapCodec CODEC = simpleCodec(ItemProviderBlock::new); + public static final EnumProperty FACING = BlockStateProperties.FACING; - public ItemProviderBlock(AbstractBlock.Settings settings) { + public ItemProviderBlock(BlockBehaviour.Properties settings) { super(settings); - this.setDefaultState(this.getDefaultState().with(FACING, Direction.UP)); + this.registerDefaultState(this.defaultBlockState().setValue(FACING, Direction.UP)); } @Override - protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder); + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); builder.add(FACING); } - public boolean canPickup(PlayerEntity player, BlockPos pos) { - return ((player.getWorld().getBlockEntity(pos) instanceof ItemProviderBlockEntity be && be.canGiveTo(player) && !player.isCreative() && be.canGiveTo(player) && (player.getMainHandStack().isEmpty() || (be.matchesStack(player.getMainHandStack()) && player.getMainHandStack().getCount() < player.getMainHandStack().getMaxCount())))); + public boolean canPickup(Player player, BlockPos pos) { + return ((player.level().getBlockEntity(pos) instanceof ItemProviderBlockEntity be && be.canGiveTo(player) && !player.isCreative() && be.canGiveTo(player) && (player.getMainHandItem().isEmpty() || (be.matchesStack(player.getMainHandItem()) && player.getMainHandItem().getCount() < player.getMainHandItem().getMaxStackSize())))); } @Override - public boolean canTarget(PlayerEntity player, BlockPos pos) { + public boolean canTarget(Player player, BlockPos pos) { return super.canTarget(player, pos) || canPickup(player, pos) || !player.isCreative(); } @Override - protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { - if (!(world.getBlockEntity(pos) instanceof ItemProviderBlockEntity be)) return ActionResult.CONSUME; + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof ItemProviderBlockEntity be)) return InteractionResult.CONSUME; if (be.canGiveTo(player)) { - if (!world.isClient) be.giveTo(player); - return ActionResult.SUCCESS; + if (!world.isClientSide()) be.giveTo(player); + return InteractionResult.SUCCESS; } - return ActionResult.CONSUME; + return InteractionResult.CONSUME; } @Override @@ -77,30 +77,30 @@ protected boolean openEditScreen(BlockPos pos) { @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new ItemProviderBlockEntity(pos, state); } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.item_provider_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.item_provider_block.tooltip.1").formatted(Formatting.DARK_GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.item_provider_block.tooltip.2").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.item_provider_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.item_provider_block.tooltip.1").withStyle(ChatFormatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.item_provider_block.tooltip.2").withStyle(ChatFormatting.DARK_GRAY)); } @Override - public BlockState getPlacementState(ItemPlacementContext ctx) { - return this.getDefaultState().with(FACING, ctx.getSide()); + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + return this.defaultBlockState().setValue(FACING, ctx.getClickedFace()); } @Override - public VoxelShape targetedOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - Vec3i facingOffset = state.get(FACING).getVector(); - return HALF_CUBED.offset(-facingOffset.getX() / 2.0F, 0, -facingOffset.getZ() / 2.0F); + public VoxelShape targetedOutlineShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + Vec3i facingOffset = state.getValue(FACING).getUnitVec3i(); + return HALF_CUBED.move(-facingOffset.getX() / 2.0F, 0, -facingOffset.getZ() / 2.0F); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/OutlineBlock.java b/src/main/java/dev/hephaestus/glowcase/block/OutlineBlock.java index 3d3072ae..4229f7e4 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/OutlineBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/OutlineBlock.java @@ -3,32 +3,32 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.OutlineBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; public class OutlineBlock extends WaterloggableGlowcaseBlock { - public static final MapCodec CODEC = createCodec(OutlineBlock::new); + public static final MapCodec CODEC = simpleCodec(OutlineBlock::new); - public OutlineBlock(AbstractBlock.Settings settings) { + public OutlineBlock(BlockBehaviour.Properties settings) { super(settings); } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new OutlineBlockEntity(pos, state); } @@ -39,13 +39,13 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.outline_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.outline_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/ParticleDisplayBlock.java b/src/main/java/dev/hephaestus/glowcase/block/ParticleDisplayBlock.java index f7871b11..ee03e178 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/ParticleDisplayBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/ParticleDisplayBlock.java @@ -3,35 +3,35 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ParticleDisplayBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityTicker; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; public class ParticleDisplayBlock extends WaterloggableGlowcaseBlock { - public static final MapCodec CODEC = createCodec(ParticleDisplayBlock::new); + public static final MapCodec CODEC = simpleCodec(ParticleDisplayBlock::new); - public ParticleDisplayBlock(AbstractBlock.Settings settings) { + public ParticleDisplayBlock(BlockBehaviour.Properties settings) { super(settings); } @Override - public @Nullable BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { - if (!world.isClient()) return null; + public @Nullable BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { + if (!world.isClientSide()) return null; return checkType(type, Glowcase.PARTICLE_DISPLAY_BLOCK_ENTITY.get(), ParticleDisplayBlockEntity::clientTick); } @@ -42,18 +42,18 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new ParticleDisplayBlockEntity(pos, state); } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.particle_display_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.particle_display_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/PopupBlock.java b/src/main/java/dev/hephaestus/glowcase/block/PopupBlock.java index d949f6f1..1bf1fb6e 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/PopupBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/PopupBlock.java @@ -3,37 +3,37 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.PopupBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.PlainTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.contents.PlainTextContents; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; public class PopupBlock extends WaterloggableGlowcaseBlock { - public static final MapCodec CODEC = createCodec(PopupBlock::new); + public static final MapCodec CODEC = simpleCodec(PopupBlock::new); - public PopupBlock(AbstractBlock.Settings settings) { + public PopupBlock(BlockBehaviour.Properties settings) { super(settings); } @Override - public VoxelShape targetedOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + public VoxelShape targetedOutlineShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return HALF_CUBED; } @@ -44,34 +44,34 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - boolean canTarget(PlayerEntity player, BlockPos pos) { + boolean canTarget(Player player, BlockPos pos) { return true; } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new PopupBlockEntity(pos, state); } @Override - protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { - if (!(world.getBlockEntity(pos) instanceof PopupBlockEntity be)) return ActionResult.CONSUME; - if (world.isClient && !(be.lines.size() == 1 && be.lines.getFirst().getContent().equals(PlainTextContent.EMPTY))) { + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof PopupBlockEntity be)) return InteractionResult.CONSUME; + if (world.isClientSide() && !(be.lines.size() == 1 && be.lines.getFirst().getContents().equals(PlainTextContents.EMPTY))) { Glowcase.proxy.openPopupBlockViewScreen(pos); } - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.popup_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.popup_block.tooltip.1").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.popup_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.popup_block.tooltip.1").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/RecipeBlock.java b/src/main/java/dev/hephaestus/glowcase/block/RecipeBlock.java index c4a3419b..0dbea7e3 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/RecipeBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/RecipeBlock.java @@ -1,40 +1,40 @@ package dev.hephaestus.glowcase.block; +import com.mojang.math.Axis; import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.RecipeBlockEntity; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.state.property.Properties; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; public class RecipeBlock extends RotatableBlock { - public static final MapCodec CODEC = createCodec(RecipeBlock::new); + public static final MapCodec CODEC = simpleCodec(RecipeBlock::new); - public RecipeBlock(AbstractBlock.Settings settings) { + public RecipeBlock(BlockBehaviour.Properties settings) { super(settings); } @@ -45,44 +45,44 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - boolean canTarget(PlayerEntity player, BlockPos pos) { + boolean canTarget(Player player, BlockPos pos) { return true; } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new RecipeBlockEntity(pos, state); } @Override - protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { - if (!(world.getBlockEntity(pos) instanceof RecipeBlockEntity be)) return ActionResult.CONSUME; + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof RecipeBlockEntity be)) return InteractionResult.CONSUME; - if (world.isClient) { + if (world.isClientSide()) { be.openRecipe(); - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } - return ActionResult.CONSUME; + return InteractionResult.CONSUME; } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.recipe_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.recipe_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override - public VoxelShape targetedOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - if (!(world.getBlockEntity(pos) instanceof RecipeBlockEntity be)) return VoxelShapes.empty(); - float rotation = -(state.get(Properties.ROTATION) * 360) / 16.0F; - Vector3f offset = new Vector3f(0, 0, be.zOffset == TextBlockEntity.ZOffset.CENTER ? 0.01F : be.zOffset == TextBlockEntity.ZOffset.FRONT ? 0.4F : -0.4F).rotate(RotationAxis.POSITIVE_Y.rotationDegrees(rotation)); - return HALF_CUBED.offset(offset.x, offset.y, offset.z); + public VoxelShape targetedOutlineShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + if (!(world.getBlockEntity(pos) instanceof RecipeBlockEntity be)) return Shapes.empty(); + float rotation = -(state.getValue(BlockStateProperties.ROTATION_16) * 360) / 16.0F; + Vector3f offset = new Vector3f(0, 0, be.zOffset == TextBlockEntity.ZOffset.CENTER ? 0.01F : be.zOffset == TextBlockEntity.ZOffset.FRONT ? 0.4F : -0.4F).rotate(Axis.YP.rotationDegrees(rotation)); + return HALF_CUBED.move(offset.x, offset.y, offset.z); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/RotatableBlock.java b/src/main/java/dev/hephaestus/glowcase/block/RotatableBlock.java index beb94e86..0ff6802a 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/RotatableBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/RotatableBlock.java @@ -1,28 +1,28 @@ package dev.hephaestus.glowcase.block; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.Properties; -import net.minecraft.util.math.MathHelper; +import net.minecraft.util.Mth; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; public abstract class RotatableBlock extends WaterloggableGlowcaseBlock { - public RotatableBlock(AbstractBlock.Settings settings) { + public RotatableBlock(BlockBehaviour.Properties settings) { super(settings); - this.setDefaultState(this.getDefaultState().with(Properties.ROTATION, 0)); + this.registerDefaultState(this.defaultBlockState().setValue(BlockStateProperties.ROTATION_16, 0)); } @Override - protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder); - builder.add(Properties.ROTATION); + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); + builder.add(BlockStateProperties.ROTATION_16); } @Override - public BlockState getPlacementState(ItemPlacementContext ctx) { - return this.getDefaultState().with(Properties.ROTATION, MathHelper.floor((double) ((180.0F + ctx.getPlayerYaw()) * 16.0F / 360.0F) + 0.5D) & 15); + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + return this.defaultBlockState().setValue(BlockStateProperties.ROTATION_16, Mth.floor((double) ((180.0F + ctx.getRotation()) * 16.0F / 360.0F) + 0.5D) & 15); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/ScreenBlock.java b/src/main/java/dev/hephaestus/glowcase/block/ScreenBlock.java index a84c1608..8f580e28 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/ScreenBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/ScreenBlock.java @@ -3,32 +3,32 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ScreenBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; public class ScreenBlock extends RotatableBlock { - public static final MapCodec CODEC = createCodec(ScreenBlock::new); + public static final MapCodec CODEC = simpleCodec(ScreenBlock::new); - public ScreenBlock(AbstractBlock.Settings settings) { + public ScreenBlock(BlockBehaviour.Properties settings) { super(settings); } @Override - public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new ScreenBlockEntity(pos, state); } @@ -39,18 +39,18 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - boolean canTarget(PlayerEntity player, BlockPos pos) { - return super.canTarget(player, pos) || player.getMainHandStack().isOf(Glowcase.TABLET_ITEM.get()); + boolean canTarget(Player player, BlockPos pos) { + return super.canTarget(player, pos) || player.getMainHandItem().is(Glowcase.TABLET_ITEM.get()); } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.screen_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.screen_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/SoundPlayerBlock.java b/src/main/java/dev/hephaestus/glowcase/block/SoundPlayerBlock.java index edcc5283..1efd6405 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/SoundPlayerBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/SoundPlayerBlock.java @@ -3,37 +3,36 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.SoundPlayerBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockEntityProvider; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityTicker; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; public class SoundPlayerBlock extends WaterloggableGlowcaseBlock { - public static final MapCodec CODEC = createCodec(SoundPlayerBlock::new); + public static final MapCodec CODEC = simpleCodec(SoundPlayerBlock::new); - public SoundPlayerBlock(AbstractBlock.Settings settings) { + public SoundPlayerBlock(BlockBehaviour.Properties settings) { super(settings); } @Nullable @Override - public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { - if (!world.isClient()) return null; + public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { + if (!world.isClientSide()) return null; return checkType(type, Glowcase.SOUND_BLOCK_ENTITY.get(), SoundPlayerBlockEntity::clientTick); } @@ -45,18 +44,18 @@ protected boolean openEditScreen(BlockPos pos) { @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new SoundPlayerBlockEntity(pos, state); } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.sound_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.sound_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/SpriteBlock.java b/src/main/java/dev/hephaestus/glowcase/block/SpriteBlock.java index c86244af..27143282 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/SpriteBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/SpriteBlock.java @@ -3,42 +3,42 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.SpriteBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.EnumProperty; -import net.minecraft.state.property.Properties; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.EnumProperty; public class SpriteBlock extends WaterloggableGlowcaseBlock { - public static final MapCodec CODEC = createCodec(SpriteBlock::new); - public static final EnumProperty FACING = Properties.FACING; + public static final MapCodec CODEC = simpleCodec(SpriteBlock::new); + public static final EnumProperty FACING = BlockStateProperties.FACING; - public SpriteBlock(AbstractBlock.Settings settings) { + public SpriteBlock(BlockBehaviour.Properties settings) { super(settings); - this.setDefaultState(this.getDefaultState().with(FACING, Direction.UP)); + this.registerDefaultState(this.defaultBlockState().setValue(FACING, Direction.UP)); } @Override - protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder); + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); builder.add(FACING); } @@ -49,38 +49,38 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - public BlockState getPlacementState(ItemPlacementContext ctx) { - return this.getDefaultState().with(FACING, ctx.getSide()); + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + return this.defaultBlockState().setValue(FACING, ctx.getClickedFace()); } @Override - public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) { + public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) { loadClientSideNBT(world, pos, placer, stack); if (placer != null && world.getBlockEntity(pos) instanceof SpriteBlockEntity be) { - if (state.get(FACING).equals(Direction.UP)) { - be.setRotation(Math.round(((540.0F + placer.getHeadYaw()) % 360.0F) / 45.0F) * 45); + if (state.getValue(FACING).equals(Direction.UP)) { + be.setRotation(Math.round(((540.0F + placer.getYHeadRot()) % 360.0F) / 45.0F) * 45); } - if (state.get(FACING).equals(Direction.DOWN)) { - be.setRotation(Math.round(((540.0F - placer.getHeadYaw()) % 360.0F) / 45.0F) * 45); + if (state.getValue(FACING).equals(Direction.DOWN)) { + be.setRotation(Math.round(((540.0F - placer.getYHeadRot()) % 360.0F) / 45.0F) * 45); } } } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new SpriteBlockEntity(pos, state); } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.sprite_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.sprite_block.tooltip.1").formatted(Formatting.DARK_GRAY)); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.sprite_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.sprite_block.tooltip.1").withStyle(ChatFormatting.DARK_GRAY)); } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/StackInteractableBlock.java b/src/main/java/dev/hephaestus/glowcase/block/StackInteractableBlock.java index 40db3711..9222314d 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/StackInteractableBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/StackInteractableBlock.java @@ -2,53 +2,53 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.StackInteractable; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; public abstract class StackInteractableBlock extends WaterloggableGlowcaseBlock { - public StackInteractableBlock(AbstractBlock.Settings settings) { + public StackInteractableBlock(BlockBehaviour.Properties settings) { super(settings); } @Override - boolean canTarget(PlayerEntity player, BlockPos pos) { - if (!(player.getWorld().getBlockEntity(pos) instanceof StackInteractable be)) return false; - return canEditGlowcase(player, pos) && (be.matchesStack(ItemStack.EMPTY) || be.matchesStack(player.getMainHandStack()) || player.getMainHandStack().isIn(Glowcase.ITEM_TAG)); + boolean canTarget(Player player, BlockPos pos) { + if (!(player.level().getBlockEntity(pos) instanceof StackInteractable be)) return false; + return canEditGlowcase(player, pos) && (be.matchesStack(ItemStack.EMPTY) || be.matchesStack(player.getMainHandItem()) || player.getMainHandItem().is(Glowcase.ITEM_TAG)); } @Override - public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { + public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { loadClientSideNBT(world, pos, placer, stack); } @Override - protected ActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - if (!(world.getBlockEntity(pos) instanceof StackInteractable be)) return ActionResult.CONSUME; + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + if (!(world.getBlockEntity(pos) instanceof StackInteractable be)) return InteractionResult.CONSUME; if (canEditGlowcase(player, pos)) { - boolean holdingGlowcaseItem = stack.isIn(Glowcase.ITEM_TAG); + boolean holdingGlowcaseItem = stack.is(Glowcase.ITEM_TAG); boolean holdingSameAsDisplay = be.matchesStack(stack); if (be.matchesStack(ItemStack.EMPTY)) { - if (!world.isClient) be.setFromStack(stack); - return ActionResult.SUCCESS; + if (!world.isClientSide()) be.setFromStack(stack); + return InteractionResult.SUCCESS; } else if (holdingSameAsDisplay) { - if (world.isClient) openEditScreen(pos); - return ActionResult.SUCCESS; + if (world.isClientSide()) openEditScreen(pos); + return InteractionResult.SUCCESS; } else if (holdingGlowcaseItem) { - if (!world.isClient) be.unsetFromStack(); - return ActionResult.SUCCESS; + if (!world.isClientSide()) be.unsetFromStack(); + return InteractionResult.SUCCESS; } } - return ActionResult.PASS_TO_DEFAULT_BLOCK_ACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/TextBlock.java b/src/main/java/dev/hephaestus/glowcase/block/TextBlock.java index 2d23d765..26853373 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/TextBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/TextBlock.java @@ -3,35 +3,36 @@ import com.mojang.serialization.MapCodec; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.NbtComponent; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtList; -import net.minecraft.nbt.NbtString; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import net.minecraft.world.item.component.TypedEntityData; +import net.minecraft.world.level.block.entity.BlockEntityType; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Optional; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; public class TextBlock extends RotatableBlock { - public static final MapCodec CODEC = createCodec(TextBlock::new); + public static final MapCodec CODEC = simpleCodec(TextBlock::new); - public TextBlock(AbstractBlock.Settings settings) { + public TextBlock(BlockBehaviour.Properties settings) { super(settings); } @@ -42,44 +43,44 @@ protected boolean openEditScreen(BlockPos pos) { } @Override - public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { + public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { if (world.getBlockEntity(pos) instanceof TextBlockEntity be) { // Wish we had ctx.side right now... - if (be.zOffset == TextBlockEntity.ZOffset.CENTER && Math.abs(placer.getPitch()) < 30) { + if (be.zOffset == TextBlockEntity.ZOffset.CENTER && Math.abs(placer.getXRot()) < 30) { be.zOffset = TextBlockEntity.ZOffset.BACK; - } else if (be.zOffset == TextBlockEntity.ZOffset.BACK && Math.abs(placer.getPitch()) > 60) { + } else if (be.zOffset == TextBlockEntity.ZOffset.BACK && Math.abs(placer.getXRot()) > 60) { be.zOffset = TextBlockEntity.ZOffset.CENTER; } - be.markDirty(); + be.setChanged(); } } @Nullable @Override - public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new TextBlockEntity(pos, state); } @Override - public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("block.glowcase.text_block.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY)); - textConsumer.accept(Text.translatable("block.glowcase.text_block.tooltip.1").formatted(Formatting.DARK_GRAY)); - NbtComponent component = stack.get(DataComponentTypes.BLOCK_ENTITY_DATA); + public void appendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("block.glowcase.text_block.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.generic.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("block.glowcase.text_block.tooltip.1").withStyle(ChatFormatting.DARK_GRAY)); + TypedEntityData> component = stack.get(DataComponents.BLOCK_ENTITY_DATA); if (component == null) return; - NbtCompound nbt = component.getNbt(); //TODO: use codecs + CompoundTag nbt = component.getUnsafe(); //TODO: use codecs if (nbt == null) return; - for (NbtElement element : nbt.getList("lines").orElse(new NbtList())) { + for (Tag element : nbt.getList("lines").orElse(new ListTag())) { Optional line = element.asString(); String lineContent; if (line.isPresent() && !(lineContent = line.get()).isBlank()) { - textConsumer.accept(Text.literal((lineContent.length() > 20 ? "%s...\"" : "%s").formatted(lineContent.substring(0, Math.min(lineContent.length(), 20)))).formatted(Formatting.DARK_PURPLE)); + textConsumer.accept(Component.literal((lineContent.length() > 20 ? "%s...\"" : "%s").formatted(lineContent.substring(0, Math.min(lineContent.length(), 20)))).withStyle(ChatFormatting.DARK_PURPLE)); } } } @Override - protected MapCodec getCodec() { + protected MapCodec codec() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/WaterloggableGlowcaseBlock.java b/src/main/java/dev/hephaestus/glowcase/block/WaterloggableGlowcaseBlock.java index 1c9d0614..9de88774 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/WaterloggableGlowcaseBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/block/WaterloggableGlowcaseBlock.java @@ -1,78 +1,78 @@ package dev.hephaestus.glowcase.block; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.Waterloggable; -import net.minecraft.entity.LivingEntity; -import net.minecraft.fluid.Fluid; -import net.minecraft.fluid.FluidState; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.item.ItemStack; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.BooleanProperty; -import net.minecraft.state.property.Properties; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.random.Random; -import net.minecraft.world.BlockView; -import net.minecraft.world.WorldAccess; -import net.minecraft.world.WorldView; -import net.minecraft.world.tick.ScheduledTickView; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.ScheduledTickAccess; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import org.jetbrains.annotations.Nullable; /** * @author Ampflower **/ -public abstract class WaterloggableGlowcaseBlock extends GlowcaseBlock implements Waterloggable { - public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; +public abstract class WaterloggableGlowcaseBlock extends GlowcaseBlock implements SimpleWaterloggedBlock { + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - public WaterloggableGlowcaseBlock(AbstractBlock.Settings settings) { + public WaterloggableGlowcaseBlock(BlockBehaviour.Properties settings) { super(settings); - this.setDefaultState(this.getDefaultState().with(WATERLOGGED, false)); + this.registerDefaultState(this.defaultBlockState().setValue(WATERLOGGED, false)); } @Override - protected boolean isTransparent(BlockState state) { + protected boolean propagatesSkylightDown(BlockState state) { return state.getFluidState().isEmpty(); } @Override - protected BlockState getStateForNeighborUpdate(BlockState state, WorldView world, ScheduledTickView tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, Random random) { - if (state.get(WATERLOGGED)) { - tickView.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { + if (state.getValue(WATERLOGGED)) { + tickView.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); } - return super.getStateForNeighborUpdate(state, world, tickView, pos, direction, neighborPos, neighborState, random); + return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); } @Override protected FluidState getFluidState(final BlockState state) { - return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state); + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } @Override - public @Nullable BlockState getPlacementState(final ItemPlacementContext ctx) { - return getDefaultState().with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER); + public @Nullable BlockState getStateForPlacement(final BlockPlaceContext ctx) { + return defaultBlockState().setValue(WATERLOGGED, ctx.getLevel().getFluidState(ctx.getClickedPos()).getType() == Fluids.WATER); } @Override - protected void appendProperties(final StateManager.Builder builder) { - super.appendProperties(builder); + protected void createBlockStateDefinition(final StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); builder.add(WATERLOGGED); } @Override - public ItemStack tryDrainFluid(@Nullable LivingEntity drainer, WorldAccess world, BlockPos pos, BlockState state) { + public ItemStack pickupBlock(@Nullable LivingEntity drainer, LevelAccessor world, BlockPos pos, BlockState state) { if (!GlowcaseBlock.canEditGlowcase(drainer, pos)) { return ItemStack.EMPTY; } - return Waterloggable.super.tryDrainFluid(drainer, world, pos, state); + return SimpleWaterloggedBlock.super.pickupBlock(drainer, world, pos, state); } @Override - public boolean canFillWithFluid(@Nullable LivingEntity filler, BlockView world, BlockPos pos, BlockState state, Fluid fluid) { - return GlowcaseBlock.canEditGlowcase(filler, pos) && Waterloggable.super.canFillWithFluid(filler, world, pos, state, fluid); + public boolean canPlaceLiquid(@Nullable LivingEntity filler, BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { + return GlowcaseBlock.canEditGlowcase(filler, pos) && SimpleWaterloggedBlock.super.canPlaceLiquid(filler, world, pos, state, fluid); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/ConfigLinkBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/ConfigLinkBlockEntity.java index c81549d6..9286c432 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/ConfigLinkBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/ConfigLinkBlockEntity.java @@ -2,12 +2,10 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.util.ConfigLinkUtil; -import net.minecraft.block.BlockState; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class ConfigLinkBlockEntity extends GlowcaseBlockEntity { public static final int TITLE_MAX_LENGTH = 1024; @@ -33,7 +31,7 @@ public String getTitle() { public void setTitle(String newTitle) { title = newTitle; - markDirty(); + setChanged(); } public String getUrl() { @@ -42,22 +40,22 @@ public String getUrl() { public void setUrl(String newUrl) { url = newUrl; - markDirty(); + setChanged(); } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); view.putString("title", this.title); view.putString("url", this.url); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - this.title = view.getString("title", ""); - this.url = view.getString("url", "glowcase:mod/modmenu"); + this.title = view.getStringOr("title", ""); + this.url = view.getStringOr("url", "glowcase:mod/modmenu"); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/DisplayBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/DisplayBlockEntity.java index 2cec8e1d..12412b73 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/DisplayBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/DisplayBlockEntity.java @@ -1,14 +1,14 @@ package dev.hephaestus.glowcase.block.entity; import dev.hephaestus.glowcase.util.DisplayBlockSettings; -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.math.BlockPos; import org.joml.Vector3f; import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public abstract class DisplayBlockEntity extends GlowcaseBlockEntity { private Vector3f offset = new Vector3f(0.0F); @@ -37,19 +37,19 @@ public void loadSettings(DisplayBlockSettings settings) { this.pitch = settings.pitch(); this.yaw = settings.yaw(); this.renderAsBlock = settings.renderAsBlock(); - markDirty(); + setChanged(); } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); DisplayBlockSettings settings = toSettings(); - if (!settings.isEmpty()) view.put("display", DisplayBlockSettings.CODEC, settings); + if (!settings.isEmpty()) view.store("display", DisplayBlockSettings.CODEC, settings); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); loadSettings(view.read("display", DisplayBlockSettings.CODEC).orElseGet(DisplayBlockSettings::new)); } @@ -71,22 +71,22 @@ public float getPitch() { public void setOffset(Vector3f offset) { this.offset = offset; - markDirty(); + setChanged(); } public void setScale(Vector3f scale) { this.scale = scale; - markDirty(); + setChanged(); } public void setYaw(float yaw) { this.yaw = yaw; - markDirty(); + setChanged(); } public void setPitch(float pitch) { this.pitch = pitch; - markDirty(); + setChanged(); } public boolean getRenderAsBlock() { @@ -95,6 +95,6 @@ public boolean getRenderAsBlock() { public void setRenderAsBlock(boolean renderAsBlock) { this.renderAsBlock = renderAsBlock; - markDirty(); + setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/EntityDisplayBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/EntityDisplayBlockEntity.java index c01c5cbf..4abf6f6a 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/EntityDisplayBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/EntityDisplayBlockEntity.java @@ -1,22 +1,22 @@ package dev.hephaestus.glowcase.block.entity; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.BlockState; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.SpawnReason; -import net.minecraft.item.ItemStack; -import net.minecraft.item.SpawnEggItem; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.tag.TagKey; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.SpawnEggItem; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; import org.joml.Vector3f; public class EntityDisplayBlockEntity extends DisplayBlockEntity implements StackInteractable { - public static final TagKey> TICK = TagKey.of(RegistryKeys.ENTITY_TYPE, Glowcase.id("tick_in_display")); + public static final TagKey> TICK = TagKey.create(Registries.ENTITY_TYPE, Glowcase.id("tick_in_display")); protected Entity displayEntity = null; protected EntityType entityType = null; @@ -27,14 +27,14 @@ public EntityDisplayBlockEntity(BlockPos pos, BlockState state) { @Override public boolean matchesStack(ItemStack stack) { - return (stack.isEmpty() && displayEntity == null) || (stack.getItem() instanceof SpawnEggItem eggItem && eggItem.isOfSameEntityType(world.getRegistryManager(), stack, entityType)); + return (stack.isEmpty() && displayEntity == null) || (stack.getItem() instanceof SpawnEggItem eggItem && SpawnEggItem.spawnsEntity( stack, entityType)); } @Override public void setFromStack(ItemStack stack) { if (stack.getItem() instanceof SpawnEggItem eggItem) { - setDisplayEntity(eggItem.getEntityType(world.getRegistryManager(), stack).create(world, SpawnReason.EVENT)); - setScale(new Vector3f(Math.clamp(Math.round(Math.min(1F / displayEntity.getHeight(), 1F / displayEntity.getWidth()) * 8F) / 8F, 0.125F, 10F))); + setDisplayEntity(SpawnEggItem.getType( stack).create(level, EntitySpawnReason.EVENT)); + setScale(new Vector3f(Math.clamp(Math.round(Math.min(1F / displayEntity.getBbHeight(), 1F / displayEntity.getBbWidth()) * 8F) / 8F, 0.125F, 10F))); } } @@ -50,29 +50,30 @@ public Entity getDisplayEntity() { public void setDisplayEntity(Entity displayEntity) { this.displayEntity = displayEntity; this.entityType = displayEntity == null ? null : displayEntity.getType(); - this.markDirty(); + this.setChanged(); } - public static void tick(World world, BlockPos blockPos, BlockState state, EntityDisplayBlockEntity blockEntity) { + public static void tick(Level world, BlockPos blockPos, BlockState state, EntityDisplayBlockEntity blockEntity) { if (blockEntity.displayEntity == null && blockEntity.entityType != null) { - blockEntity.setDisplayEntity(blockEntity.entityType.create(world, SpawnReason.EVENT)); + blockEntity.setDisplayEntity(blockEntity.entityType.create(world, EntitySpawnReason.EVENT)); } - if (blockEntity.getDisplayEntity() != null && blockEntity.getDisplayEntity().getType().isIn(TICK)) { - ++blockEntity.displayEntity.age; +// if (blockEntity.getDisplayEntity() != null && blockEntity.getDisplayEntity().getType().is(TICK)) { + if (blockEntity.getDisplayEntity() != null && blockEntity.getDisplayEntity().getType().builtInRegistryHolder().is(TICK)) { + ++blockEntity.displayEntity.tickCount; } } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); if (entityType != null) { - view.put("type", EntityType.CODEC, entityType); + view.store("type", EntityType.CODEC, entityType); } } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); this.entityType = view.read("type", EntityType.CODEC).orElse(null); this.displayEntity = null; diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/GlowcaseBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/GlowcaseBlockEntity.java index 759f5e08..8f28913f 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/GlowcaseBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/GlowcaseBlockEntity.java @@ -1,16 +1,15 @@ package dev.hephaestus.glowcase.block.entity; -import dev.hephaestus.glowcase.client.render.block.entity.BakedBlockEntityRenderer; -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.network.listener.ClientPlayPacketListener; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; public class GlowcaseBlockEntity extends BlockEntity { @@ -19,28 +18,28 @@ public GlowcaseBlockEntity(BlockEntityType type, BlockPos pos, BlockState sta } @Override - public void markDirty() { - super.markDirty(); - if (world instanceof ServerWorld sw) sw.getChunkManager().markForUpdate(pos); + public void setChanged() { + super.setChanged(); + if (level instanceof ServerLevel sw) sw.getChunkSource().blockChanged(worldPosition); } @Override - public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registryLookup) { - return createNbt(registryLookup); + public CompoundTag getUpdateTag(HolderLookup.Provider registryLookup) { + return saveWithoutMetadata(registryLookup); } @Nullable @Override - public Packet toUpdatePacket() { - return BlockEntityUpdateS2CPacket.create(this); + public Packet getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); } - @SuppressWarnings({"MethodCallSideOnly", "VariableUseSideOnly"}) - @Override - public void markRemoved() { - if (world != null && world.isClient) { - BakedBlockEntityRenderer.Manager.markForRebuild(getPos()); - } - super.markRemoved(); - } +// @SuppressWarnings({"MethodCallSideOnly", "VariableUseSideOnly"}) +// @Override +// public void setRemoved() { +// if (level != null && level.isClientSide()) { +// BakedBlockEntityRenderer.Manager.markForRebuild(getBlockPos()); +// } +// super.setRemoved(); +// } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/HyperlinkBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/HyperlinkBlockEntity.java index 827cb518..79ba4ff1 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/HyperlinkBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/HyperlinkBlockEntity.java @@ -1,12 +1,10 @@ package dev.hephaestus.glowcase.block.entity; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.BlockState; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class HyperlinkBlockEntity extends GlowcaseBlockEntity { public static final int TITLE_MAX_LENGTH = 1024; @@ -28,7 +26,7 @@ public String getTitle() { public void setTitle(String newTitle) { title = newTitle; - markDirty(); + setChanged(); } public String getUrl() { @@ -37,23 +35,23 @@ public String getUrl() { public void setUrl(String newUrl) { url = newUrl; - markDirty(); + setChanged(); } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); view.putString("title", this.title); view.putString("url", this.url); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - this.title = view.getString("title", ""); - this.url = view.getString("url", ""); + this.title = view.getStringOr("title", ""); + this.url = view.getStringOr("url", ""); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/InfiniteInventory.java b/src/main/java/dev/hephaestus/glowcase/block/entity/InfiniteInventory.java index c752f5dd..60d10503 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/InfiniteInventory.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/InfiniteInventory.java @@ -1,10 +1,10 @@ package dev.hephaestus.glowcase.block.entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.Inventory; -import net.minecraft.item.ItemStack; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; -public interface InfiniteInventory extends Inventory { +public interface InfiniteInventory extends Container { ItemStack getStack(); default boolean hasItem() { @@ -12,7 +12,7 @@ default boolean hasItem() { } @Override - default int size() { + default int getContainerSize() { return 1; } @@ -22,30 +22,30 @@ default boolean isEmpty() { } @Override - default ItemStack getStack(int slot) { + default ItemStack getItem(int slot) { return getStack().copyWithCount(1); } @Override - default ItemStack removeStack(int slot, int amount) { + default ItemStack removeItem(int slot, int amount) { return getStack().copyWithCount(1); } @Override - default ItemStack removeStack(int slot) { + default ItemStack removeItemNoUpdate(int slot) { return getStack().copyWithCount(1); } @Override - default void setStack(int slot, ItemStack stack) { + default void setItem(int slot, ItemStack stack) { } @Override - default boolean canPlayerUse(PlayerEntity player) { + default boolean stillValid(Player player) { return false; } @Override - default void clear() { + default void clearContent() { } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/ItemAcceptorBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/ItemAcceptorBlockEntity.java index 670e2f4b..6b423651 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/ItemAcceptorBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/ItemAcceptorBlockEntity.java @@ -2,28 +2,25 @@ import com.mojang.serialization.Codec; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.BlockState; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.registry.tag.TagKey; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.Identifier; -import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.Util; -import net.minecraft.util.math.BlockPos; - import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.tags.TagKey; +import net.minecraft.util.StringRepresentable; +import net.minecraft.util.Util; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class ItemAcceptorBlockEntity extends GlowcaseBlockEntity { - private Identifier item = Identifier.ofVanilla("air"); + private Identifier item = Identifier.withDefaultNamespace("air"); public int count = 1; public int pulse = 4; public OutputDirection outputDirection = OutputDirection.BACK; @@ -35,24 +32,24 @@ public ItemAcceptorBlockEntity(BlockPos pos, BlockState state) { } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); - view.put("item", Identifier.CODEC, this.item); + view.store("item", Identifier.CODEC, this.item); view.putInt("count", this.count); view.putInt("pulse", this.pulse); view.putBoolean("is_item_tag", this.isItemTag); - view.put("output_direction", OutputDirection.CODEC, this.outputDirection); + view.store("output_direction", OutputDirection.CODEC, this.outputDirection); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - this.setItem(view.read("item", Identifier.CODEC).orElse(Identifier.ofVanilla("air"))); - this.count = view.getInt("count", 1); - this.pulse = view.getInt("pulse", 4); - this.isItemTag = view.getBoolean("is_item_tag", false); + this.setItem(view.read("item", Identifier.CODEC).orElse(Identifier.withDefaultNamespace("air"))); + this.count = view.getIntOr("count", 1); + this.pulse = view.getIntOr("pulse", 4); + this.isItemTag = view.getBooleanOr("is_item_tag", false); this.outputDirection = view.read("output_direction", OutputDirection.CODEC).orElse(OutputDirection.BACK); } @@ -67,8 +64,8 @@ public void setItem(Identifier item) { this.item = item; - TagKey itemTag = TagKey.of(RegistryKeys.ITEM, item); - itemTagList = Registries.ITEM.stream().filter(it -> it.getDefaultStack().isIn(itemTag)).toList(); + TagKey itemTag = TagKey.create(Registries.ITEM, item); + itemTagList = BuiltInRegistries.ITEM.stream().filter(it -> it.getDefaultInstance().is(itemTag)).toList(); } public ItemStack getDisplayItemStack() { @@ -77,16 +74,16 @@ public ItemStack getDisplayItemStack() { return ItemStack.EMPTY; } - return itemTagList.get((int) (Util.getMeasuringTimeMs() / 1000f) % itemTagList.size()).getDefaultStack(); + return itemTagList.get((int) (Util.getMillis() / 1000f) % itemTagList.size()).getDefaultInstance(); } else { - return Registries.ITEM.get(item).getDefaultStack(); + return BuiltInRegistries.ITEM.getValue(item).getDefaultInstance(); } } public boolean isItemAccepted(ItemStack stack) { boolean isEqual = isItemTag - ? stack.isIn(TagKey.of(RegistryKeys.ITEM, item)) - : stack.isOf(Registries.ITEM.get(item)); + ? stack.is(TagKey.create(Registries.ITEM, item)) + : stack.is(BuiltInRegistries.ITEM.getValue(item)); return isEqual && stack.getCount() >= count; } @@ -95,13 +92,13 @@ public int getPulse() { return pulse; } - public enum OutputDirection implements StringIdentifiable { + public enum OutputDirection implements StringRepresentable { TOP, BACK, BOTTOM; - public static final Codec CODEC = StringIdentifiable.createCodec(OutputDirection::values); + public static final Codec CODEC = StringRepresentable.fromEnum(OutputDirection::values); @Override - public String asString() { + public String getSerializedName() { return name().toLowerCase(Locale.ROOT); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/ItemDisplayBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/ItemDisplayBlockEntity.java index eb79954e..2ae286d6 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/ItemDisplayBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/ItemDisplayBlockEntity.java @@ -1,14 +1,11 @@ package dev.hephaestus.glowcase.block.entity; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.BlockState; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class ItemDisplayBlockEntity extends DisplayBlockEntity implements StackInteractable { protected ItemStack stack = ItemStack.EMPTY; @@ -19,19 +16,19 @@ public ItemStack getStack() { @Override public boolean matchesStack(ItemStack stack) { - return ItemStack.areItemsEqual(this.stack, stack); + return ItemStack.isSameItem(this.stack, stack); } @Override public void setFromStack(ItemStack stack) { this.stack = stack.copy(); - this.markDirty(); + this.setChanged(); } @Override public void unsetFromStack() { this.stack = ItemStack.EMPTY; - this.markDirty(); + this.setChanged(); } public ItemDisplayBlockEntity(BlockPos pos, BlockState state) { @@ -39,15 +36,15 @@ public ItemDisplayBlockEntity(BlockPos pos, BlockState state) { } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); - if (!this.stack.isEmpty()) view.put("item", ItemStack.CODEC, this.stack); + if (!this.stack.isEmpty()) view.store("item", ItemStack.CODEC, this.stack); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); this.stack = view.read("item", ItemStack.CODEC).orElse(ItemStack.EMPTY); } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/ItemProviderBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/ItemProviderBlockEntity.java index c0d76f01..b998d747 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/ItemProviderBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/ItemProviderBlockEntity.java @@ -2,20 +2,16 @@ import com.mojang.serialization.Codec; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.Hand; -import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.Uuids; -import net.minecraft.util.math.BlockPos; - import java.util.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.UUIDUtil; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class ItemProviderBlockEntity extends GlowcaseBlockEntity implements InfiniteInventory, StackInteractable { protected ItemStack stack = ItemStack.EMPTY; @@ -30,20 +26,20 @@ public ItemProviderBlockEntity(BlockPos pos, BlockState state) { @Override public boolean matchesStack(ItemStack stack) { - return ItemStack.areItemsEqual(this.stack, stack); + return ItemStack.isSameItem(this.stack, stack); } @Override public void setFromStack(ItemStack stack) { this.stack = stack.copy(); this.givenTimes.clear(); - this.markDirty(); + this.setChanged(); } @Override public void unsetFromStack() { this.stack = ItemStack.EMPTY; - this.markDirty(); + this.setChanged(); } @Override @@ -61,83 +57,83 @@ public boolean isInvisible() { public void setGivesItem(GivesItem givesItem) { this.givesItem = givesItem; - markDirty(); + setChanged(); } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); - if (!this.stack.isEmpty()) view.put("item", ItemStack.CODEC, this.stack); - view.put("gives_item", GivesItem.CODEC, this.givesItem); + if (!this.stack.isEmpty()) view.store("item", ItemStack.CODEC, this.stack); + view.store("gives_item", GivesItem.CODEC, this.givesItem); view.putLong("cooldown", this.cooldown); - view.put("given_times", Codec.unboundedMap(Uuids.CODEC, Codec.LONG), givenTimes); + view.store("given_times", Codec.unboundedMap(UUIDUtil.AUTHLIB_CODEC, Codec.LONG), givenTimes); view.putBoolean("invisible", this.invisible); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); this.stack = view.read("item", ItemStack.CODEC).orElse(ItemStack.EMPTY); this.givesItem = view.read("gives_item", GivesItem.CODEC).orElse(GivesItem.ALWAYS); - this.cooldown = view.getLong("cooldown", 0); - this.givenTimes = new HashMap<>(view.read("given_times", Codec.unboundedMap(Uuids.CODEC, Codec.LONG)).orElseGet(() -> Map.of())); - this.invisible = view.getBoolean("invisible", false); + this.cooldown = view.getLongOr("cooldown", 0); + this.givenTimes = new HashMap<>(view.read("given_times", Codec.unboundedMap(UUIDUtil.AUTHLIB_CODEC, Codec.LONG)).orElseGet(() -> Map.of())); + this.invisible = view.getBooleanOr("invisible", false); } public void cycleGiveType() { this.givesItem = GivesItem.values()[(this.givesItem.ordinal() + 1) % GivesItem.values().length]; givenTimes.clear(); - markDirty(); + setChanged(); } - public long getCooldownTicks(PlayerEntity player) { - return givenTimes.containsKey(player.getUuid()) ? givenTimes.get(player.getUuid()) + this.cooldown * 20 - world.getTime() : 0; + public long getCooldownTicks(Player player) { + return givenTimes.containsKey(player.getUUID()) ? givenTimes.get(player.getUUID()) + this.cooldown * 20 - level.getGameTime() : 0; } - public boolean canGiveTo(PlayerEntity player) { + public boolean canGiveTo(Player player) { if (!hasItem()) return false; else return switch (this.givesItem) { case ALWAYS -> true; case TIMED -> player.isCreative() || getCooldownTicks(player) <= 0; - case ONE -> player.isCreative() || !player.getInventory().containsAny(Set.of(stack.getItem())); + case ONE -> player.isCreative() || !player.getInventory().hasAnyOf(Set.of(stack.getItem())); }; } - public void giveTo(PlayerEntity player) { - ItemStack itemStack = player.getStackInHand(Hand.MAIN_HAND); - boolean holdingSameAsDisplay = ItemStack.areItemsAndComponentsEqual(getStack(), itemStack); + public void giveTo(Player player) { + ItemStack itemStack = player.getItemInHand(InteractionHand.MAIN_HAND); + boolean holdingSameAsDisplay = ItemStack.isSameItemSameComponents(getStack(), itemStack); if (itemStack.isEmpty()) { ItemStack stackToGive = getStack().copy(); - if (player.isSneaking()) { - stackToGive.setCount(stackToGive.getMaxCount()); + if (player.isShiftKeyDown()) { + stackToGive.setCount(stackToGive.getMaxStackSize()); } - player.setStackInHand(Hand.MAIN_HAND, stackToGive); + player.setItemInHand(InteractionHand.MAIN_HAND, stackToGive); } else if (holdingSameAsDisplay) { - itemStack.increment(getStack().getCount()); - itemStack.capCount(itemStack.getMaxCount()); - player.setStackInHand(Hand.MAIN_HAND, itemStack); + itemStack.grow(getStack().getCount()); + itemStack.limitSize(itemStack.getMaxStackSize()); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); } else { return; } if (!player.isCreative()) { - givenTimes.put(player.getUuid(), world.getTime()); - markDirty(); + givenTimes.put(player.getUUID(), level.getGameTime()); + setChanged(); } } - public enum GivesItem implements StringIdentifiable { + public enum GivesItem implements StringRepresentable { ALWAYS, TIMED, ONE; - public static final Codec CODEC = StringIdentifiable.createCodec(GivesItem::values); + public static final Codec CODEC = StringRepresentable.fromEnum(GivesItem::values); @Override - public String asString() { + public String getSerializedName() { return name().toLowerCase(Locale.ROOT); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/OutlineBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/OutlineBlockEntity.java index bd9b860f..563ea337 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/OutlineBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/OutlineBlockEntity.java @@ -1,15 +1,12 @@ package dev.hephaestus.glowcase.block.entity; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.BlockState; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3i; - import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class OutlineBlockEntity extends GlowcaseBlockEntity { public Vec3i offset = Vec3i.ZERO; @@ -21,20 +18,20 @@ public OutlineBlockEntity(BlockPos pos, BlockState state) { } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); - view.put("offset", Vec3i.CODEC, this.offset); - view.put("scale", Vec3i.CODEC, this.scale); + view.store("offset", Vec3i.CODEC, this.offset); + view.store("scale", Vec3i.CODEC, this.scale); view.putInt("color", this.color); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); this.offset = view.read("offset", Vec3i.CODEC).orElse(Vec3i.ZERO); this.scale = view.read("scale", Vec3i.CODEC).orElseGet(() -> new Vec3i(1, 1, 1)); - this.color = view.getInt("color", 0xFFFFFF); + this.color = view.getIntOr("color", 0xFFFFFF); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/ParticleDisplayBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/ParticleDisplayBlockEntity.java index 3e3fbc28..9c18ade8 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/ParticleDisplayBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/ParticleDisplayBlockEntity.java @@ -6,25 +6,21 @@ import dev.hephaestus.glowcase.util.DeviatedVec3d; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.block.BlockState; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtOps; -import net.minecraft.particle.ParticleEffect; -import net.minecraft.particle.ParticleTypes; -import net.minecraft.registry.RegistryOps; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; +import net.minecraft.world.phys.Vec3; import org.slf4j.Logger; public class ParticleDisplayBlockEntity extends GlowcaseBlockEntity { private static final Logger LOGGER = LogUtils.getLogger(); - public ParticleEffect particle = ParticleTypes.FLAME; + public ParticleOptions particle = ParticleTypes.FLAME; public DeviatedVec3d position = DeviatedVec3d.ZERO; public DeviatedVec3d velocity = DeviatedVec3d.ZERO; public DeviatedInteger count = DeviatedInteger.ZERO; @@ -37,21 +33,21 @@ public ParticleDisplayBlockEntity(BlockPos pos, BlockState state) { } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); - view.put("particle", ParticleTypes.TYPE_CODEC, this.particle); - view.put("position", DeviatedVec3d.CODEC, this.position); - view.put("velocity", DeviatedVec3d.CODEC, this.velocity); - view.put("count", DeviatedInteger.CODEC, this.count); - view.put("tick_rate", DeviatedInteger.CODEC, this.tickRate); + view.store("particle", ParticleTypes.CODEC, this.particle); + view.store("position", DeviatedVec3d.CODEC, this.position); + view.store("velocity", DeviatedVec3d.CODEC, this.velocity); + view.store("count", DeviatedInteger.CODEC, this.count); + view.store("tick_rate", DeviatedInteger.CODEC, this.tickRate); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - this.particle = view.read("particle", ParticleTypes.TYPE_CODEC).orElse(ParticleTypes.FLAME); + this.particle = view.read("particle", ParticleTypes.CODEC).orElse(ParticleTypes.FLAME); this.position = view.read("position", DeviatedVec3d.CODEC).orElse(DeviatedVec3d.ZERO); this.velocity = view.read("velocity", DeviatedVec3d.CODEC).orElse(DeviatedVec3d.ZERO); this.count = view.read("count", DeviatedInteger.CODEC).orElse(DeviatedInteger.ZERO); @@ -59,16 +55,17 @@ protected void readData(ReadView view) { } @Environment(EnvType.CLIENT) - public static void clientTick(World world, BlockPos pos, BlockState state, ParticleDisplayBlockEntity entity) { + public static void clientTick(Level world, BlockPos pos, BlockState state, ParticleDisplayBlockEntity entity) { entity.tickCounter--; if (entity.tickCounter > 0) return; - entity.tickCounter = entity.tickRate.get(world.random::nextDouble); - for (int i = 0; i < entity.count.get(world.random::nextDouble); i++) { - Vec3d particlePos = entity.position.get(world.random::nextGaussian).add(pos.toCenterPos()); - Vec3d particleVelocity = entity.velocity.get(world.random::nextGaussian); + var random = world.getRandom(); + entity.tickCounter = entity.tickRate.get(random::nextDouble); + for (int i = 0; i < entity.count.get(random::nextDouble); i++) { + Vec3 particlePos = entity.position.get(random::nextGaussian).add(pos.getCenter()); + Vec3 particleVelocity = entity.velocity.get(random::nextGaussian); - world.addParticleClient( + world.addParticle( entity.particle, particlePos.x, particlePos.y, particlePos.z, particleVelocity.x, particleVelocity.y, particleVelocity.z diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/PopupBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/PopupBlockEntity.java index 9801817b..acb2d4ea 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/PopupBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/PopupBlockEntity.java @@ -4,53 +4,51 @@ import eu.pb4.placeholders.api.ParserContext; import eu.pb4.placeholders.api.parsers.NodeParser; import eu.pb4.placeholders.api.parsers.TagParser; -import net.minecraft.block.BlockState; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.text.TextCodecs; -import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.math.BlockPos; - import java.util.ArrayList; import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.chat.Style; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class PopupBlockEntity extends GlowcaseBlockEntity { public static final NodeParser PARSER = TagParser.DEFAULT; public String title = ""; - public List lines = new ArrayList<>(); + public List lines = new ArrayList<>(); public TextBlockEntity.TextAlignment textAlignment = TextBlockEntity.TextAlignment.CENTER; public int color = 0xFFFFFFFF; public boolean renderDirty = true; public PopupBlockEntity(BlockPos pos, BlockState state) { super(Glowcase.POPUP_BLOCK_ENTITY.get(), pos, state); - lines.add(Text.empty()); + lines.add(Component.empty()); } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); view.putString("title", this.title); view.putInt("color", this.color); - view.put("text_alignment", TextBlockEntity.TextAlignment.CODEC, this.textAlignment); + view.store("text_alignment", TextBlockEntity.TextAlignment.CODEC, this.textAlignment); - view.put("lines", TextCodecs.CODEC.listOf(), this.lines); + view.store("lines", ComponentSerialization.CODEC.listOf(), this.lines); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - this.title = view.getString("title", ""); - this.color = view.getInt("color", 0xFFFFFF); + this.title = view.getStringOr("title", ""); + this.color = view.getIntOr("color", 0xFFFFFF); this.textAlignment = view.read("text_alignment", TextBlockEntity.TextAlignment.CODEC).orElse(TextBlockEntity.TextAlignment.CENTER); - this.lines = new ArrayList<>(view.read("lines", TextCodecs.CODEC.listOf()).orElse(List.of(Text.empty()))); + this.lines = new ArrayList<>(view.read("lines", ComponentSerialization.CODEC.listOf()).orElse(List.of(Component.empty()))); this.renderDirty = true; } @@ -71,22 +69,22 @@ public String getRawLine(int i) { } public void addRawLine(int i, String string) { - var parsed = PARSER.parseText(string, ParserContext.of()); + var parsed = PARSER.parseComponent(string, ParserContext.of()); if (parsed.getString().equals(string)) { - this.lines.add(i, Text.literal(string)); + this.lines.add(i, Component.literal(string)); } else { - this.lines.add(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); + this.lines.add(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); } } public void setRawLine(int i, String string) { - var parsed = PARSER.parseText(string, ParserContext.of()); + var parsed = PARSER.parseComponent(string, ParserContext.of()); if (parsed.getString().equals(string)) { - this.lines.set(i, Text.literal(string)); + this.lines.set(i, Component.literal(string)); } else { - this.lines.set(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); + this.lines.set(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/RecipeBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/RecipeBlockEntity.java index 292376c8..c64ebe1c 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/RecipeBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/RecipeBlockEntity.java @@ -3,12 +3,12 @@ import dev.hephaestus.glowcase.Glowcase; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.block.BlockState; -import net.minecraft.component.ComponentsAccess; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponentGetter; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class RecipeBlockEntity extends GlowcaseBlockEntity { public String recipe = "diamond_sword"; @@ -32,31 +32,31 @@ public void openRecipe() { public void setRecipe(String newRecipe) { recipe = newRecipe; - markDirty(); + setChanged(); } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); view.putString("recipe", this.recipe); - view.put("z_offset", TextBlockEntity.ZOffset.CODEC, this.zOffset); + view.store("z_offset", TextBlockEntity.ZOffset.CODEC, this.zOffset); view.putFloat("rotationX", this.rotationX); view.putFloat("rotationY", this.rotationY); } @Override - protected void readComponents(ComponentsAccess components) { - super.readComponents(components); + protected void applyImplicitComponents(DataComponentGetter components) { + super.applyImplicitComponents(components); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - this.recipe = view.getString("recipe", "diamond_sword"); + this.recipe = view.getStringOr("recipe", "diamond_sword"); this.zOffset = view.read("z_offset", TextBlockEntity.ZOffset.CODEC).orElse(TextBlockEntity.ZOffset.CENTER); - this.rotationX = view.getFloat("rotationX", 0); - this.rotationY = view.getFloat("rotationY", 0); + this.rotationX = view.getFloatOr("rotationX", 0); + this.rotationY = view.getFloatOr("rotationY", 0); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/ScreenBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/ScreenBlockEntity.java index a14fc41a..1b692e2b 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/ScreenBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/ScreenBlockEntity.java @@ -3,15 +3,15 @@ import com.mojang.datafixers.util.Pair; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.client.GlowcaseClient; -import net.minecraft.block.BlockState; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.Uuids; -import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; import java.util.UUID; +import net.minecraft.core.BlockPos; +import net.minecraft.core.UUIDUtil; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class ScreenBlockEntity extends GlowcaseBlockEntity { public static final int URL_MAX_LENGTH = 1024; @@ -77,10 +77,10 @@ public ScreenBlockEntity(BlockPos pos, BlockState state) { } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); - view.put("macaddress", Uuids.INT_STREAM_CODEC, macaddress); + view.store("macaddress", UUIDUtil.CODEC, macaddress); view.putFloat("width", width); view.putFloat("height", height); @@ -107,39 +107,39 @@ protected void writeData(WriteView view) { } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - macaddress = view.read("macaddress", Uuids.INT_STREAM_CODEC).orElseGet(UUID::randomUUID); + macaddress = view.read("macaddress", UUIDUtil.CODEC).orElseGet(UUID::randomUUID); - width = view.getFloat("width", 1); - height = view.getFloat("height", 1); + width = view.getFloatOr("width", 1); + height = view.getFloatOr("height", 1); - renderBackface = view.getBoolean("renderBackface", false); - stretch = view.getBoolean("stretch", false); - eink = view.getBoolean("eink", false); + renderBackface = view.getBooleanOr("renderBackface", false); + stretch = view.getBooleanOr("stretch", false); + eink = view.getBooleanOr("eink", false); - xOffset = Offset.fromOffset(view.getInt("x_offset", 0)); - yOffset = Offset.fromOffset(view.getInt("y_offset", 0)); - zOffset = Offset.fromOffset(view.getInt("z_offset", 0)); + xOffset = Offset.fromOffset(view.getIntOr("x_offset", 0)); + yOffset = Offset.fromOffset(view.getIntOr("y_offset", 0)); + zOffset = Offset.fromOffset(view.getIntOr("z_offset", 0)); - preciseX = view.getFloat("px", 0); - preciseY = view.getFloat("py", 0); - preciseZ = view.getFloat("pz", 0); + preciseX = view.getFloatOr("px", 0); + preciseY = view.getFloatOr("py", 0); + preciseZ = view.getFloatOr("pz", 0); - pitch = view.getFloat("pitch", 0); - yaw = view.getFloat("yaw", 0); + pitch = view.getFloatOr("pitch", 0); + yaw = view.getFloatOr("yaw", 0); - url = view.getString("url", ""); - alt = view.getString("alt", ""); + url = view.getStringOr("url", ""); + alt = view.getStringOr("alt", ""); // Cache preview before needed for smooth experience - preview = view.getString("preview", ""); - if (this.getWorld() != null && this.getWorld().isClient()) { + preview = view.getStringOr("preview", ""); + if (this.getLevel() != null && this.getLevel().isClientSide()) { GlowcaseClient.screenImageCache.getImage(preview, null); } - markDirty(); + setChanged(); } public void setImage(String url, String alt, @Nullable String preview) { @@ -149,7 +149,7 @@ public void setImage(String url, String alt, @Nullable String preview) { if (preview != null) this.preview = preview; - markDirty(); + setChanged(); } public void setupScreen(float width, float height, Offset xOffset, Offset yOffset, Offset zOffset, float pitch, float yaw, boolean eink, boolean stretch, boolean renderBackface) { @@ -203,6 +203,6 @@ public void setOffset(Vector3f offset) { this.preciseY = offset.y(); this.preciseZ = offset.z(); - markDirty(); + setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/SoundPlayerBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/SoundPlayerBlockEntity.java index 644fc81f..93289e73 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/SoundPlayerBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/SoundPlayerBlockEntity.java @@ -6,23 +6,23 @@ import dev.hephaestus.glowcase.client.util.SoundPlayerProxy; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.client.sound.AbstractSoundInstance; -import net.minecraft.client.sound.SoundInstance; -import net.minecraft.client.sound.SoundManager; -import net.minecraft.client.sound.TickableSoundInstance; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvents; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.Identifier; -import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.resources.sounds.AbstractSoundInstance; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.resources.sounds.TickableSoundInstance; +import net.minecraft.client.sounds.SoundManager; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.Identifier; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; +import net.minecraft.world.phys.Vec3; import org.slf4j.Logger; import java.util.Locale; @@ -30,14 +30,14 @@ public class SoundPlayerBlockEntity extends GlowcaseBlockEntity { private static final Logger LOGGER = LogUtils.getLogger(); - public Identifier soundId = SoundEvents.ENTITY_CAT_PURREOW.id(); - public SoundCategory category = SoundCategory.BLOCKS; + public Identifier soundId = SoundEvents.CAT_PURREOW_BABY.key().identifier(); + public SoundSource category = SoundSource.BLOCKS; public float volume = 1; public float pitch = 1; public int repeatDelay = 0; public float distance = 16; public boolean relative = false; - public Vec3d offset = Vec3d.ZERO; + public Vec3 offset = Vec3.ZERO; public boolean cancelOthers = false; public PositionSampler volumeSampler = PositionSampler.CAMERA; @@ -48,14 +48,14 @@ public SoundPlayerBlockEntity(BlockPos pos, BlockState state) { } public void cycleCategory() { - this.category = SoundCategory.values()[(this.category.ordinal() + 1) % SoundCategory.values().length]; + this.category = SoundSource.values()[(this.category.ordinal() + 1) % SoundSource.values().length]; } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); - view.put("sound", Identifier.CODEC, this.soundId); + view.store("sound", Identifier.CODEC, this.soundId); view.putString("category", this.category.name()); view.putFloat("volume", this.volume); view.putFloat("pitch", this.pitch); @@ -63,30 +63,30 @@ protected void writeData(WriteView view) { view.putFloat("distance", this.distance); view.putBoolean("relative", this.relative); view.putBoolean("cancelOthers", this.cancelOthers); - view.put("offset", Vec3d.CODEC, this.offset); - view.put("volumeSampler", PositionSampler.CODEC, volumeSampler); + view.store("offset", Vec3.CODEC, this.offset); + view.store("volumeSampler", PositionSampler.CODEC, volumeSampler); } @Override - protected void readData(ReadView view) { - super.readData(view); - - this.soundId = view.read("sound", Identifier.CODEC).orElseGet(SoundEvents.ENTITY_CAT_PURREOW::id); - - this.category = SoundCategory.valueOf(view.getString("category", SoundCategory.BLOCKS.name())); - this.volume = view.getFloat("volume", 1); - this.pitch = view.getFloat("pitch", 1); - this.repeatDelay = view.getInt("repeatDelay", 0); - this.distance = view.getFloat("distance", 16); - this.relative = view.getBoolean("relative", false); - this.cancelOthers = view.getBoolean("cancelOthers", false); - this.offset = view.read("offset", Vec3d.CODEC).orElse(Vec3d.ZERO); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); + + this.soundId = view.read("sound", Identifier.CODEC).orElseGet(() -> SoundEvents.CAT_PURREOW_BABY.key().identifier()); + + this.category = SoundSource.valueOf(view.getStringOr("category", SoundSource.BLOCKS.name())); + this.volume = view.getFloatOr("volume", 1); + this.pitch = view.getFloatOr("pitch", 1); + this.repeatDelay = view.getIntOr("repeatDelay", 0); + this.distance = view.getFloatOr("distance", 16); + this.relative = view.getBooleanOr("relative", false); + this.cancelOthers = view.getBooleanOr("cancelOthers", false); + this.offset = view.read("offset", Vec3.CODEC).orElse(Vec3.ZERO); this.volumeSampler = view.read("volumeSampler", PositionSampler.CODEC).orElse(PositionSampler.CAMERA); } @Environment(EnvType.CLIENT) - public static void clientTick(World world, BlockPos pos, BlockState state, SoundPlayerBlockEntity entity) { - final MinecraftClient client = MinecraftClient.getInstance(); + public static void clientTick(Level world, BlockPos pos, BlockState state, SoundPlayerBlockEntity entity) { + final Minecraft client = Minecraft.getInstance(); final SoundManager soundManager = client.getSoundManager(); final PositionedSoundLoop oldInstance = entity.nowPlaying; @@ -99,15 +99,15 @@ public static void clientTick(World world, BlockPos pos, BlockState state, Sound soundManager.stop(oldInstance); } - final Vec3d cameraPos = client.gameRenderer.getCamera().getPos(); - final Vec3d sourcePos = entity.getSourcePos(); + final Vec3 cameraPos = client.gameRenderer.getMainCamera().position(); + final Vec3 sourcePos = entity.getSourcePos(); - if (cameraPos.squaredDistanceTo(sourcePos) > entity.distanceSquared()) { + if (cameraPos.distanceToSqr(sourcePos) > entity.distanceSquared()) { return; } if (entity.cancelOthers) { - soundManager.stopSounds(null, entity.category); + soundManager.stop(null, entity.category); } PositionedSoundLoop sound = new PositionedSoundLoop(entity); @@ -117,20 +117,20 @@ public static void clientTick(World world, BlockPos pos, BlockState state, Sound soundManager.play(sound); } - private Vec3d getSoundPos() { + private Vec3 getSoundPos() { if (relative) { return offset; } - return pos.toCenterPos().add(offset); + return worldPosition.getCenter().add(offset); } - private Vec3d getSourcePos() { + private Vec3 getSourcePos() { if (relative) { - return pos.toCenterPos(); + return worldPosition.getCenter(); } - return pos.toCenterPos().add(offset); + return worldPosition.getCenter().add(offset); } private float distanceSquared() { @@ -138,29 +138,29 @@ private float distanceSquared() { } - public enum PositionSampler implements StringIdentifiable { + public enum PositionSampler implements StringRepresentable { CAMERA { @Override - public Vec3d getPosition(final MinecraftClient client) { - return client.gameRenderer.getCamera().getPos(); + public Vec3 getPosition(final Minecraft client) { + return client.gameRenderer.getMainCamera().position(); } }, PLAYER { @Override - public Vec3d getPosition(final MinecraftClient client) { + public Vec3 getPosition(final Minecraft client) { if (client.player == null) { - return Vec3d.ZERO; + return Vec3.ZERO; } - return client.player.getPos(); + return client.player.position(); } }; - public static final Codec CODEC = StringIdentifiable.createCodec(PositionSampler::values); + public static final Codec CODEC = StringRepresentable.fromEnum(PositionSampler::values); - public abstract Vec3d getPosition(MinecraftClient client); + public abstract Vec3 getPosition(Minecraft client); @Override - public String asString() { + public String getSerializedName() { return name().toLowerCase(Locale.ROOT); } } @@ -172,9 +172,9 @@ public static class PositionedSoundLoop extends AbstractSoundInstance implements private boolean done; public PositionedSoundLoop(SoundPlayerBlockEntity soundBlock) { - super(soundBlock.soundId, soundBlock.category, SoundInstance.createRandom()); - this.repeat = true; - this.attenuationType = AttenuationType.NONE; + super(soundBlock.soundId, soundBlock.category, SoundInstance.createUnseededRandom()); + this.looping = true; + this.attenuation = Attenuation.NONE; this.relative = soundBlock.relative; this.soundBlock = soundBlock; this.done = false; @@ -182,12 +182,12 @@ public PositionedSoundLoop(SoundPlayerBlockEntity soundBlock) { } @Override - public boolean isDone() { + public boolean isStopped() { return this.done; } public void setDone() { - this.repeat = false; + this.looping = false; this.done = true; } @@ -198,15 +198,15 @@ public void tick() { return; } - final MinecraftClient client = MinecraftClient.getInstance(); + final Minecraft client = Minecraft.getInstance(); // If the worlds don't match, stop. - if (this.soundBlock.getWorld() != client.world) { + if (this.soundBlock.getLevel() != client.level) { this.setDone(); return; } - if (!inRange(client.player, client.gameRenderer.getCamera())) { + if (!inRange(client.player, client.gameRenderer.getMainCamera())) { setDone(); return; } @@ -218,13 +218,13 @@ private void copyData() { this.setPos(soundBlock.getSoundPos()); this.volume = this.soundBlock.volume; this.pitch = this.soundBlock.pitch; - this.repeatDelay = this.soundBlock.repeatDelay; + this.delay = this.soundBlock.repeatDelay; } - private void setPos(Vec3d pos) { - this.x = pos.getX(); - this.y = pos.getY(); - this.z = pos.getZ(); + private void setPos(Vec3 pos) { + this.x = pos.x(); + this.y = pos.y(); + this.z = pos.z(); } @Override @@ -235,30 +235,30 @@ public float getVolume() { } private float linearFalloff() { - final Vec3d position = this.soundBlock.volumeSampler.getPosition(MinecraftClient.getInstance()); + final Vec3 position = this.soundBlock.volumeSampler.getPosition(Minecraft.getInstance()); float distanceToCamera = (float) this.soundBlock.getSourcePos().distanceTo(position); return 1 - (distanceToCamera / this.soundBlock.distance); } - public boolean inRange(ClientPlayerEntity player, Camera camera) { + public boolean inRange(LocalPlayer player, Camera camera) { final float maxDistSquared = this.soundBlock.distanceSquared(); - final Vec3d sourcePos = this.soundBlock.getSourcePos(); + final Vec3 sourcePos = this.soundBlock.getSourcePos(); - if (camera.getPos().squaredDistanceTo(sourcePos) <= maxDistSquared) { + if (camera.position().distanceToSqr(sourcePos) <= maxDistSquared) { return true; } - return player.squaredDistanceTo(sourcePos) <= maxDistSquared; + return player.distanceToSqr(sourcePos) <= maxDistSquared; } public boolean isCompatible() { - if (this.isDone() || this.soundBlock.nowPlaying != this) { + if (this.isStopped() || this.soundBlock.nowPlaying != this) { return false; } return this.relative == this.soundBlock.relative && - this.id.equals(this.soundBlock.soundId) && - this.category.equals(this.soundBlock.category); + this.identifier.equals(this.soundBlock.soundId) && + this.source.equals(this.soundBlock.category); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/SpriteBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/SpriteBlockEntity.java index b6a0a4b2..6425ae4b 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/SpriteBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/SpriteBlockEntity.java @@ -1,19 +1,17 @@ package dev.hephaestus.glowcase.block.entity; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.BlockState; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.Identifier; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class SpriteBlockEntity extends GlowcaseBlockEntity { protected String sprite = "arrow"; @@ -30,7 +28,7 @@ public SpriteBlockEntity(BlockPos pos, BlockState state) { public void setSprite(String newSprite) { sprite = newSprite; if (newSprite.contains(":")) { - Optional item = Registries.ITEM.getOptionalValue(Identifier.tryParse(newSprite)); + Optional item = BuiltInRegistries.ITEM.getOptional(Identifier.tryParse(newSprite)); renderItem = item.map(ItemStack::new).orElse(null); } else { renderItem = null; @@ -47,29 +45,29 @@ public ItemStack getRenderItem() { } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); view.putString("sprite", this.sprite); view.putInt("rotation", this.rotation); - view.put("z_offset", TextBlockEntity.ZOffset.CODEC, this.zOffset); + view.store("z_offset", TextBlockEntity.ZOffset.CODEC, this.zOffset); view.putInt("color", this.color); view.putFloat("scale", this.scale); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - setSprite(view.getString("sprite", "arrow")); - this.rotation = view.getInt("rotation", 0); + setSprite(view.getStringOr("sprite", "arrow")); + this.rotation = view.getIntOr("rotation", 0); this.zOffset = view.read("z_offset", TextBlockEntity.ZOffset.CODEC).orElse(TextBlockEntity.ZOffset.BACK); - this.color = view.getInt("color", 0xFFFFFF); - this.scale = view.getFloat("scale", 1); + this.color = view.getIntOr("color", 0xFFFFFF); + this.scale = view.getFloatOr("scale", 1); } public void setRotation(int rotation) { this.rotation = rotation; - markDirty(); + setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/StackInteractable.java b/src/main/java/dev/hephaestus/glowcase/block/entity/StackInteractable.java index 70e41d02..263bf95e 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/StackInteractable.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/StackInteractable.java @@ -1,6 +1,6 @@ package dev.hephaestus.glowcase.block.entity; -import net.minecraft.item.ItemStack; +import net.minecraft.world.item.ItemStack; public interface StackInteractable { boolean matchesStack(ItemStack stack); diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java index 1b48d9a8..9e19fede 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java @@ -6,25 +6,24 @@ import eu.pb4.placeholders.api.ParserContext; import eu.pb4.placeholders.api.parsers.NodeParser; import eu.pb4.placeholders.api.parsers.TagParser; -import net.minecraft.block.BlockState; -import net.minecraft.storage.ReadView; -import net.minecraft.storage.WriteView; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.text.TextCodecs; -import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.math.BlockPos; - import java.util.ArrayList; import java.util.List; import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.chat.Style; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; public class TextBlockEntity extends GlowcaseBlockEntity { public static final NodeParser PARSER = TagParser.DEFAULT; public static final int PLATE_BACKGROUND = 0x44000000; - public List lines = new ArrayList<>(); + public List lines = new ArrayList<>(); public TextAlignment textAlignment = TextAlignment.CENTER; public ZOffset zOffset = ZOffset.CENTER; public boolean shadow = true; @@ -36,43 +35,43 @@ public class TextBlockEntity extends GlowcaseBlockEntity { public TextBlockEntity(BlockPos pos, BlockState state) { super(Glowcase.TEXT_BLOCK_ENTITY.get(), pos, state); - lines.add(Text.empty()); + lines.add(Component.empty()); } @Override - protected void writeData(WriteView view) { - super.writeData(view); + protected void saveAdditional(ValueOutput view) { + super.saveAdditional(view); view.putFloat("scale", this.scale); view.putInt("color", this.color); view.putInt("background_color", this.backgroundColor); - view.put("text_alignment", TextAlignment.CODEC, this.textAlignment); - view.put("z_offset", ZOffset.CODEC, this.zOffset); + view.store("text_alignment", TextAlignment.CODEC, this.textAlignment); + view.store("z_offset", ZOffset.CODEC, this.zOffset); view.putBoolean("shadow", this.shadow); view.putFloat("viewDistance", this.viewDistance); - view.put("lines", TextCodecs.CODEC.listOf(), lines); + view.store("lines", ComponentSerialization.CODEC.listOf(), lines); } @Override - protected void readData(ReadView view) { - super.readData(view); + protected void loadAdditional(ValueInput view) { + super.loadAdditional(view); - this.scale = view.getFloat("scale", 1); - this.color = view.getInt("color", 0xFFFFFFFF); + this.scale = view.getFloatOr("scale", 1); + this.color = view.getIntOr("color", 0xFFFFFFFF); // Force-fix alpha of 0 to opaque. if ((this.color & ColorUtil.ALPHA_MASK) == 0) { this.color |= ColorUtil.ALPHA_MASK; } - this.backgroundColor = view.getInt("background_color", 0); - this.shadow = view.getBoolean("shadow", true); + this.backgroundColor = view.getIntOr("background_color", 0); + this.shadow = view.getBooleanOr("shadow", true); this.textAlignment = view.read("text_alignment", TextAlignment.CODEC).orElse(TextAlignment.CENTER); this.zOffset = view.read("z_offset", ZOffset.CODEC).orElse(ZOffset.CENTER); - this.viewDistance = view.getFloat("viewDistance", -1); - this.lines = new ArrayList<>(view.read("lines", TextCodecs.CODEC.listOf()).orElseGet(List::of)); + this.viewDistance = view.getFloatOr("viewDistance", -1); + this.lines = new ArrayList<>(view.read("lines", ComponentSerialization.CODEC.listOf()).orElseGet(List::of)); this.renderDirty = true; } @@ -92,43 +91,43 @@ public String getRawLine(int i) { } public void addRawLine(int i, String string) { - var parsed = PARSER.parseText(string, ParserContext.of()); + var parsed = PARSER.parseComponent(string, ParserContext.of()); if (parsed.getString().equals(string)) { - this.lines.add(i, Text.literal(string)); + this.lines.add(i, Component.literal(string)); } else { - this.lines.add(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); + this.lines.add(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); } } public void setRawLine(int i, String string) { - var parsed = PARSER.parseText(string, ParserContext.of()); + var parsed = PARSER.parseComponent(string, ParserContext.of()); if (parsed.getString().equals(string)) { - this.lines.set(i, Text.literal(string)); + this.lines.set(i, Component.literal(string)); } else { - this.lines.set(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); + this.lines.set(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); } } - public enum TextAlignment implements StringIdentifiable { + public enum TextAlignment implements StringRepresentable { LEFT, CENTER, CENTER_LEFT, CENTER_RIGHT, RIGHT; - public static final Codec CODEC = StringIdentifiable.createCodec(TextAlignment::values); + public static final Codec CODEC = StringRepresentable.fromEnum(TextAlignment::values); @Override - public String asString() { + public String getSerializedName() { return name().toLowerCase(); } } - public enum ZOffset implements StringIdentifiable { + public enum ZOffset implements StringRepresentable { FRONT, CENTER, BACK; - public static final Codec CODEC = StringIdentifiable.createCodec(ZOffset::values); + public static final Codec CODEC = StringRepresentable.fromEnum(ZOffset::values); @Override - public String asString() { + public String getSerializedName() { return name().toLowerCase(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClient.java b/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClient.java index aa1589fb..4f42dc5f 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClient.java +++ b/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClient.java @@ -8,24 +8,24 @@ import dev.hephaestus.glowcase.client.render.item.tint.GlowcaseTintSource; import dev.hephaestus.glowcase.client.util.NoteTextColorResource; import dev.hephaestus.glowcase.item.ScrollableItem; -import dev.hephaestus.glowcase.mixin.HandledScreenInvoker; +import dev.hephaestus.glowcase.mixin.AbstractContainerScreenInvoker; import dev.hephaestus.glowcase.packet.C2SSlotScrolled; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.rendering.v1.InvalidateRenderStateCallback; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderEvents; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactories; -import net.minecraft.client.render.item.tint.TintSourceTypes; -import net.minecraft.item.ItemStack; -import net.minecraft.resource.ResourceType; -import net.minecraft.screen.slot.Slot; -import net.minecraft.util.Identifier; +import net.minecraft.client.Minecraft; +import net.minecraft.client.color.item.ItemTintSources; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.PackType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; public class GlowcaseClient implements ClientModInitializer { public static final Boolean EMI_LOADED = FabricLoader.getInstance().isModLoaded("emi"); @@ -38,30 +38,31 @@ public class GlowcaseClient implements ClientModInitializer { public void onInitializeClient() { Glowcase.proxy = new GlowcaseClientProxy(); - BlockEntityRendererFactories.register(Glowcase.TEXT_BLOCK_ENTITY.get(), TextBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.HYPERLINK_BLOCK_ENTITY.get(), HyperlinkBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.CONFIG_LINK_BLOCK_ENTITY.get(), ConfigLinkBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.ITEM_DISPLAY_BLOCK_ENTITY.get(), ItemDisplayBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.POPUP_BLOCK_ENTITY.get(), PopupBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.SCREEN_BLOCK_ENTITY.get(), ScreenBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.SPRITE_BLOCK_ENTITY.get(), SpriteBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.RECIPE_BLOCK_ENTITY.get(), RecipeBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.OUTLINE_BLOCK_ENTITY.get(), OutlineBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.PARTICLE_DISPLAY_BLOCK_ENTITY.get(), ParticleDisplayBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.SOUND_BLOCK_ENTITY.get(), SoundPlayerBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.ITEM_ACCEPTOR_BLOCK_ENTITY.get(), ItemAcceptorBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.ITEM_PROVIDER_BLOCK_ENTITY.get(), ItemProviderBlockEntityRenderer::new); - BlockEntityRendererFactories.register(Glowcase.ENTITY_DISPLAY_BLOCK_ENTITY.get(), EntityDisplayBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.TEXT_BLOCK_ENTITY.get(), (ctx) -> new TextBlockEntityRenderer()); + BlockEntityRenderers.register(Glowcase.HYPERLINK_BLOCK_ENTITY.get(), HyperlinkBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.CONFIG_LINK_BLOCK_ENTITY.get(), ConfigLinkBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.ITEM_DISPLAY_BLOCK_ENTITY.get(), ItemDisplayBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.POPUP_BLOCK_ENTITY.get(), PopupBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.SCREEN_BLOCK_ENTITY.get(), ScreenBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.SPRITE_BLOCK_ENTITY.get(), SpriteBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.RECIPE_BLOCK_ENTITY.get(), RecipeBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.OUTLINE_BLOCK_ENTITY.get(), OutlineBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.PARTICLE_DISPLAY_BLOCK_ENTITY.get(), ParticleDisplayBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.SOUND_BLOCK_ENTITY.get(), SoundPlayerBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.ITEM_ACCEPTOR_BLOCK_ENTITY.get(), ItemAcceptorBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.ITEM_PROVIDER_BLOCK_ENTITY.get(), ItemProviderBlockEntityRenderer::new); + BlockEntityRenderers.register(Glowcase.ENTITY_DISPLAY_BLOCK_ENTITY.get(), EntityDisplayBlockEntityRenderer::new); ItemHandRenderer.register(Glowcase.TABLET_ITEM.get().asItem(), new TabletItemHandRenderer()); ItemHandRenderer.register(Glowcase.NOTE_ITEM.get().asItem(), new NoteItemHandRenderer()); - TintSourceTypes.ID_MAPPER.put(Glowcase.id("auto"), GlowcaseTintSource.CODEC); + ItemTintSources.ID_MAPPER.put(Glowcase.id("auto"), GlowcaseTintSource.CODEC); - WorldRenderEvents.AFTER_ENTITIES.register(BakedBlockEntityRenderer.Manager::render); - InvalidateRenderStateCallback.EVENT.register(BakedBlockEntityRenderer.Manager::reset); + //FIXME 26.1 +// LevelRenderEvents.AFTER_OPAQUE_TERRAIN.register(BakedBlockEntityRenderer.Manager::render); +// InvalidateRenderStateCallback.EVENT.register(BakedBlockEntityRenderer.Manager::reset); - ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new NoteTextColorResource()); + ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new NoteTextColorResource()); /*ModelPredicateProviderRegistryAccessor.callRegister(Identifier.of("glowcase:awakened"), (stack, world, entity, seed) -> { if (!EMI_LOADED) { @@ -89,8 +90,8 @@ public void onInitializeClient() { });*/ ScreenEvents.BEFORE_INIT.register(((client, sc, scaledWidth, scaledHeight) -> { - if (sc instanceof HandledScreen hs) { - ScreenMouseEvents.allowMouseScroll(hs).register((screen, x, y, h, v) -> allowMouseScroll((HandledScreen) screen, x, y, v)); + if (sc instanceof AbstractContainerScreen hs) { + ScreenMouseEvents.allowMouseScroll(hs).register((screen, x, y, h, v) -> allowMouseScroll((AbstractContainerScreen) screen, x, y, v)); } })); @@ -105,10 +106,10 @@ public void onInitializeClient() { /** * @author zacharybarbanell */ - private boolean allowMouseScroll(HandledScreen screen, double x, double y, double scroll) { - Slot slot = ((HandledScreenInvoker) screen).invokeGetSlotAt(x, y); + private boolean allowMouseScroll(AbstractContainerScreen screen, double x, double y, double scroll) { + Slot slot = ((AbstractContainerScreenInvoker) screen).invokeGetSlotAt(x, y); if (slot == null) return true; - ItemStack stack = slot.getStack(); + ItemStack stack = slot.getItem(); if (!(stack.getItem() instanceof ScrollableItem si)) return true; if (accScroll * scroll < 0) { accScroll = 0; @@ -117,8 +118,8 @@ private boolean allowMouseScroll(HandledScreen screen, double x, double y, do int amount = (int) accScroll; if (amount == 0) return true; accScroll -= amount; - si.scroll(stack, MinecraftClient.getInstance().player, amount); - ClientPlayNetworking.send(new C2SSlotScrolled(screen.getScreenHandler().syncId, screen.getScreenHandler().getRevision(), slot.id, amount)); + si.scroll(stack, Minecraft.getInstance().player, amount); + ClientPlayNetworking.send(new C2SSlotScrolled(screen.getMenu().containerId, screen.getMenu().getStateId(), slot.index, amount)); return false; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClientProxy.java b/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClientProxy.java index a9dfc371..7caa9d3d 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClientProxy.java +++ b/src/main/java/dev/hephaestus/glowcase/client/GlowcaseClientProxy.java @@ -33,157 +33,157 @@ import dev.hephaestus.glowcase.client.gui.screen.ingame.TabletEditScreen; import dev.hephaestus.glowcase.client.gui.screen.ingame.TextBlockEditScreen; import dev.hephaestus.glowcase.client.util.ConfigLinkClientUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.ConfirmLinkScreen; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.ConfirmLinkScreen; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; public class GlowcaseClientProxy extends GlowcaseCommonProxy { @Override public void openConfigLinkBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof ConfigLinkBlockEntity be) { - MinecraftClient.getInstance().setScreen(new ConfigLinkBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof ConfigLinkBlockEntity be) { + Minecraft.getInstance().setScreen(new ConfigLinkBlockEditScreen(be)); } } @Override public void openConfigScreen(String link) { - MinecraftClient client = MinecraftClient.getInstance(); + Minecraft client = Minecraft.getInstance(); client.setScreen(ConfigLinkClientUtil.getConfigScreen(client, link)); } @Override public void openHyperlinkBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof HyperlinkBlockEntity be) { - MinecraftClient.getInstance().setScreen(new HyperlinkBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof HyperlinkBlockEntity be) { + Minecraft.getInstance().setScreen(new HyperlinkBlockEditScreen(be)); } } @Override public void openUrlWithConfirmation(String url) { - ConfirmLinkScreen.open(MinecraftClient.getInstance().currentScreen, url); + ConfirmLinkScreen.confirmLinkNow(Minecraft.getInstance().screen, url); } @Override public void openItemDisplayBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof ItemDisplayBlockEntity be) { - MinecraftClient.getInstance().setScreen(new ItemDisplayEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof ItemDisplayBlockEntity be) { + Minecraft.getInstance().setScreen(new ItemDisplayEditScreen(be)); } } @Override public void openItemProviderBlockEditScreen(BlockPos pos){ - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof ItemProviderBlockEntity be) { - MinecraftClient.getInstance().setScreen(new ItemProviderBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof ItemProviderBlockEntity be) { + Minecraft.getInstance().setScreen(new ItemProviderBlockEditScreen(be)); } } @Override public void openTextBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof TextBlockEntity be) { - MinecraftClient.getInstance().setScreen(new TextBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof TextBlockEntity be) { + Minecraft.getInstance().setScreen(new TextBlockEditScreen(be)); } } @Override public void openPopupBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof PopupBlockEntity be) { - MinecraftClient.getInstance().setScreen(new PopupBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof PopupBlockEntity be) { + Minecraft.getInstance().setScreen(new PopupBlockEditScreen(be)); } } @Override public void openPopupBlockViewScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof PopupBlockEntity be) { - MinecraftClient.getInstance().setScreen(new PopupBlockViewScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof PopupBlockEntity be) { + Minecraft.getInstance().setScreen(new PopupBlockViewScreen(be)); } } @Override public void openScreenBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof ScreenBlockEntity be) { - MinecraftClient.getInstance().setScreen(new ScreenBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof ScreenBlockEntity be) { + Minecraft.getInstance().setScreen(new ScreenBlockEditScreen(be)); } } @Override public void openRecipeBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof RecipeBlockEntity be) { - MinecraftClient.getInstance().setScreen(new RecipeBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof RecipeBlockEntity be) { + Minecraft.getInstance().setScreen(new RecipeBlockEditScreen(be)); } } @Override public void openSpriteBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof SpriteBlockEntity be) { - MinecraftClient.getInstance().setScreen(new SpriteBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof SpriteBlockEntity be) { + Minecraft.getInstance().setScreen(new SpriteBlockEditScreen(be)); } } @Override public void openOutlineBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof OutlineBlockEntity be) { - MinecraftClient.getInstance().setScreen(new OutlineBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof OutlineBlockEntity be) { + Minecraft.getInstance().setScreen(new OutlineBlockEditScreen(be)); } } @Override public void openParticleDisplayBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof ParticleDisplayBlockEntity be) { - MinecraftClient.getInstance().setScreen(new ParticleDisplayEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof ParticleDisplayBlockEntity be) { + Minecraft.getInstance().setScreen(new ParticleDisplayEditScreen(be)); } } @Override public void openSoundBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof SoundPlayerBlockEntity be) { - MinecraftClient.getInstance().setScreen(new SoundPlayerBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof SoundPlayerBlockEntity be) { + Minecraft.getInstance().setScreen(new SoundPlayerBlockEditScreen(be)); } } @Override public void openItemAcceptorBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity be) { - MinecraftClient.getInstance().setScreen(new ItemAcceptorBlockEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof ItemAcceptorBlockEntity be) { + Minecraft.getInstance().setScreen(new ItemAcceptorBlockEditScreen(be)); } } @Override public void openTabletEditScreen(ItemStack stack) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null) { - MinecraftClient.getInstance().setScreen(new TabletEditScreen(stack)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null) { + Minecraft.getInstance().setScreen(new TabletEditScreen(stack)); } } @Override public void openNoteEditScreen(ItemStack stack) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null) { - MinecraftClient.getInstance().setScreen(new NoteEditScreen(stack)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null) { + Minecraft.getInstance().setScreen(new NoteEditScreen(stack)); } } @Override public void openEntityDisplayBlockEditScreen(BlockPos pos) { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.world != null && client.world.getBlockEntity(pos) instanceof EntityDisplayBlockEntity be) { - MinecraftClient.getInstance().setScreen(new EntityDisplayEditScreen(be)); + Minecraft client = Minecraft.getInstance(); + if (client.level != null && client.level.getBlockEntity(pos) instanceof EntityDisplayBlockEntity be) { + Minecraft.getInstance().setScreen(new EntityDisplayEditScreen(be)); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/GlowcaseRenderLayers.java b/src/main/java/dev/hephaestus/glowcase/client/GlowcaseRenderLayers.java index 8830eb00..089ec933 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/GlowcaseRenderLayers.java +++ b/src/main/java/dev/hephaestus/glowcase/client/GlowcaseRenderLayers.java @@ -2,58 +2,60 @@ import com.mojang.blaze3d.pipeline.RenderPipeline; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; - import java.util.function.BiFunction; import java.util.function.Function; -public abstract class GlowcaseRenderLayers extends RenderLayer { - public static final Function SCREEN_PROGRAM = Util.memoize((culling) -> RenderPipelines.register( - RenderPipeline.builder(RenderPipelines.TEXT_SNIPPET, RenderPipelines.FOG_SNIPPET) - .withLocation(Glowcase.id("pipeline/screen")) - .withVertexShader("core/rendertype_text") - .withFragmentShader("core/rendertype_text") - .withCull(culling) - .withSampler("Sampler0") - .withSampler("Sampler2") - .withDepthBias(-1.0F, -1.0F) - .build() - )); - - public static final RenderPipeline TEXT_PLATE_PROGRAM = RenderPipelines.register( - RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET).withLocation(Glowcase.id("pipeline/text_plate")).withCull(false).build() - ); - - // Use a custom render layer to render the text plate - mimics DrawableHelper's RenderSystem call - public static final RenderLayer TEXT_PLATE = RenderLayer.of("glowcase_text_plate", - 256, - true, - true, - TEXT_PLATE_PROGRAM, - RenderLayer.MultiPhaseParameters.builder().texture(NO_TEXTURE).build(false)); - - - private static final BiFunction SCREEN = Util.memoize((texture, culling) -> { - return RenderLayer.of( - "glowcase_screen", - 786432, - false, - true, - SCREEN_PROGRAM.apply(culling), - MultiPhaseParameters.builder() - .texture(new Texture(texture, false)) - .lightmap(ENABLE_LIGHTMAP) - .build(false)); - }); - - public GlowcaseRenderLayers(String name, int size, boolean hasCrumbling, boolean translucent, Runnable begin, Runnable end) { - super(name, size, hasCrumbling, translucent, begin, end); - } - - public static RenderLayer getScreen(Identifier texture, boolean culling) { - return SCREEN.apply(texture, culling); - } -} +import net.minecraft.client.renderer.rendertype.RenderType; +import net.minecraft.util.Util; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.resources.Identifier; + +import static net.minecraft.client.renderer.RenderPipelines.LIGHTMAP; +// +//public abstract class GlowcaseRenderLayers extends RenderType { +// public static final Function SCREEN_PROGRAM = Util.memoize((culling) -> RenderPipelines.register( +// RenderPipeline.builder(RenderPipelines.TEXT_SNIPPET, RenderPipelines.FOG_SNIPPET) +// .withLocation(Glowcase.id("pipeline/screen")) +// .withVertexShader("core/rendertype_text") +// .withFragmentShader("core/rendertype_text") +// .withCull(culling) +// .withSampler("Sampler0") +// .withSampler("Sampler2") +// .withDepthBias(-1.0F, -1.0F) +// .build() +// )); +// +// public static final RenderPipeline TEXT_PLATE_PROGRAM = RenderPipelines.register( +// RenderPipeline.builder(RenderPipelines.DEBUG_FILLED_SNIPPET).withLocation(Glowcase.id("pipeline/text_plate")).withCull(false).build() +// ); +// +// // Use a custom render layer to render the text plate - mimics DrawableHelper's RenderSystem call +// public static final RenderType TEXT_PLATE = RenderType.create("glowcase_text_plate", +// 256, +// true, +// true, +// TEXT_PLATE_PROGRAM, +// RenderType.CompositeState.builder().setTextureState(NO_TEXTURE).createCompositeState(false)); +// +// +// private static final BiFunction SCREEN = Util.memoize((texture, culling) -> { +// return RenderType.create( +// "glowcase_screen", +// 786432, +// false, +// true, +// SCREEN_PROGRAM.apply(culling), +// CompositeState.builder() +// .setTextureState(new TextureStateShard(texture, false)) +// .setLightmapState(LIGHTMAP) +// .createCompositeState(false)); +// }); +// +// public GlowcaseRenderLayers(String name, int size, boolean hasCrumbling, boolean translucent, Runnable begin, Runnable end) { +// super(name, size, hasCrumbling, translucent, begin, end); +// } +// +// public static RenderType getScreen(Identifier texture, boolean culling) { +// return SCREEN.apply(texture, culling); +// } +//} diff --git a/src/main/java/dev/hephaestus/glowcase/client/ScreenImageCache.java b/src/main/java/dev/hephaestus/glowcase/client/ScreenImageCache.java index 49fad7f0..1bdc4ea8 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/ScreenImageCache.java +++ b/src/main/java/dev/hephaestus/glowcase/client/ScreenImageCache.java @@ -1,20 +1,20 @@ package dev.hephaestus.glowcase.client; +import com.mojang.blaze3d.platform.NativeImage; import com.mojang.datafixers.util.Pair; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.client.util.HTTPException; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.resource.Resource; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; -import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.imageio.ImageIO; +import net.minecraft.util.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.resources.Resource; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; @@ -197,10 +197,10 @@ public ScreenTexture(int code) { */ public ScreenTexture(@NotNull Identifier texture) { // Get width/height - Optional resource = MinecraftClient.getInstance().getResourceManager().getResource(texture); + Optional resource = Minecraft.getInstance().getResourceManager().getResource(texture); if (resource.isPresent()) try { - InputStream inputStream = resource.get().getInputStream(); + InputStream inputStream = resource.get().open(); BufferedImage image = ImageIO.read(inputStream); width = image.getWidth(); @@ -221,7 +221,7 @@ public ScreenTexture(URL url) { HttpURLConnection connection; InputStream stream; try { - connection = (HttpURLConnection) url.openConnection(MinecraftClient.getInstance().getNetworkProxy()); + connection = (HttpURLConnection) url.openConnection(Minecraft.getInstance().getProxy()); connection.setDoInput(true); connection.setDoOutput(false); connection.connect(); @@ -248,24 +248,24 @@ public ScreenTexture(URL url) { // TODO: Perhaps adding a local file cache might be wise - int result = MinecraftClient.getInstance().submit(() -> { + int result = Minecraft.getInstance().submit(() -> { width = nativeImage.getWidth(); height = nativeImage.getHeight(); String imageHash = Integer.toHexString(nativeImage.hashCode()); - NativeImageBackedTexture nativeTexture = new NativeImageBackedTexture(() -> imageHash, nativeImage); + DynamicTexture nativeTexture = new DynamicTexture(() -> imageHash, nativeImage); // Register image as texture - TextureManager textureManager = MinecraftClient.getInstance().getTextureManager(); + TextureManager textureManager = Minecraft.getInstance().getTextureManager(); this.texture = Glowcase.id("glowcase/img", imageHash); - textureManager.registerTexture(this.texture, nativeTexture); + textureManager.register(this.texture, nativeTexture); return 200; }).join(); connection.disconnect(); return result; - }, Util.getMainWorkerExecutor()); + }, Util.backgroundExecutor()); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ColorPickerIncludedScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ColorPickerIncludedScreen.java index caebf76e..531b9f90 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ColorPickerIncludedScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ColorPickerIncludedScreen.java @@ -1,11 +1,11 @@ package dev.hephaestus.glowcase.client.gui.screen.ingame; import dev.hephaestus.glowcase.client.gui.widget.ingame.ColorPickerWidget; -import net.minecraft.util.Formatting; +import net.minecraft.ChatFormatting; public interface ColorPickerIncludedScreen { ColorPickerWidget colorPickerWidget(); void toggleColorPicker(boolean active); void insertHexTag(String hex); - void insertFormattingTag(Formatting formatting); + void insertFormattingTag(ChatFormatting formatting); } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ConfigLinkBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ConfigLinkBlockEditScreen.java index 7eb0aeb4..48dbec91 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ConfigLinkBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ConfigLinkBlockEditScreen.java @@ -4,15 +4,16 @@ import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditConfigLinkBlock; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.Text; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.network.chat.Component; import org.lwjgl.glfw.GLFW; public class ConfigLinkBlockEditScreen extends GlowcaseScreen { private final ConfigLinkBlockEntity configLinkBlockEntity; - private TextFieldWidget titleEntryWidget; - private TextFieldWidget urlEntryWidget; + private EditBox titleEntryWidget; + private EditBox urlEntryWidget; public ConfigLinkBlockEditScreen(ConfigLinkBlockEntity configLinkBlockEntity) { this.configLinkBlockEntity = configLinkBlockEntity; @@ -22,41 +23,42 @@ public ConfigLinkBlockEditScreen(ConfigLinkBlockEntity configLinkBlockEntity) { public void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; - this.titleEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 10, height / 2 - 30, 8 * width / 10, 20, Text.empty()); + this.titleEntryWidget = new EditBox(this.minecraft.font, width / 10, height / 2 - 30, 8 * width / 10, 20, Component.empty()); this.titleEntryWidget.setMaxLength(HyperlinkBlockEntity.TITLE_MAX_LENGTH); - this.titleEntryWidget.setText(this.configLinkBlockEntity.getTitle()); - this.titleEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.title")); + this.titleEntryWidget.setValue(this.configLinkBlockEntity.getTitle()); + this.titleEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.title")); - this.urlEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 10, height / 2 + 10, 8 * width / 10, 20, Text.empty()); + this.urlEntryWidget = new EditBox(this.minecraft.font, width / 10, height / 2 + 10, 8 * width / 10, 20, Component.empty()); this.urlEntryWidget.setMaxLength(HyperlinkBlockEntity.URL_MAX_LENGTH); - this.urlEntryWidget.setText(this.configLinkBlockEntity.getUrl()); - this.urlEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.url")); + this.urlEntryWidget.setValue(this.configLinkBlockEntity.getUrl()); + this.urlEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.url")); - this.addDrawableChild(this.titleEntryWidget); - this.addDrawableChild(this.urlEntryWidget); + this.addRenderableWidget(this.titleEntryWidget); + this.addRenderableWidget(this.urlEntryWidget); } - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + @Override + public boolean keyPressed(KeyEvent event) { + int keyCode = event.key(); if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER || keyCode == GLFW.GLFW_KEY_ESCAPE) { - this.close(); + this.onClose(); return true; - } else if (this.titleEntryWidget.isActive()) { - return this.titleEntryWidget.keyPressed(keyCode, scanCode, modifiers); - } else if (this.urlEntryWidget.isActive()) { - return this.urlEntryWidget.keyPressed(keyCode, scanCode, modifiers); + } else if (this.titleEntryWidget.canConsumeInput()) { + return this.titleEntryWidget.keyPressed(event); + } else if (this.urlEntryWidget.canConsumeInput()) { + return this.urlEntryWidget.keyPressed(event); } else { return false; } } @Override - public void close() { - configLinkBlockEntity.setUrl(urlEntryWidget.getText()); - configLinkBlockEntity.setTitle(titleEntryWidget.getText()); + public void onClose() { + configLinkBlockEntity.setUrl(urlEntryWidget.getValue()); + configLinkBlockEntity.setTitle(titleEntryWidget.getValue()); C2SEditConfigLinkBlock.of(configLinkBlockEntity).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/DisplayBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/DisplayBlockEditScreen.java index ce6f8998..d738fac4 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/DisplayBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/DisplayBlockEditScreen.java @@ -1,10 +1,10 @@ package dev.hephaestus.glowcase.client.gui.screen.ingame; import dev.hephaestus.glowcase.block.entity.DisplayBlockEntity; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.Text; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.network.chat.Component; import org.joml.Vector3f; import com.google.common.primitives.Floats; @@ -12,26 +12,26 @@ public abstract class DisplayBlockEditScreen extends GlowcaseScreen { protected final DisplayBlockEntity displayBlock; - protected TextFieldWidget scaleField; - protected TextFieldWidget xOffsetField; - protected TextFieldWidget yOffsetField; - protected TextFieldWidget zOffsetField; - protected TextFieldWidget pitchField; - protected TextFieldWidget yawField; - - protected ButtonWidget decreaseSize; - protected ButtonWidget increaseSize; - - protected ButtonWidget decreaseXOffset; - protected ButtonWidget increaseXOffset; - protected ButtonWidget decreaseYOffset; - protected ButtonWidget increaseYOffset; - protected ButtonWidget decreaseZOffset; - protected ButtonWidget increaseZOffset; - protected ButtonWidget decreasePitch; - protected ButtonWidget increasePitch; - protected ButtonWidget decreaseYaw; - protected ButtonWidget increaseYaw; + protected EditBox scaleField; + protected EditBox xOffsetField; + protected EditBox yOffsetField; + protected EditBox zOffsetField; + protected EditBox pitchField; + protected EditBox yawField; + + protected Button decreaseSize; + protected Button increaseSize; + + protected Button decreaseXOffset; + protected Button increaseXOffset; + protected Button decreaseYOffset; + protected Button increaseYOffset; + protected Button decreaseZOffset; + protected Button increaseZOffset; + protected Button decreasePitch; + protected Button increasePitch; + protected Button decreaseYaw; + protected Button increaseYaw; private final float pitchYawChange = 15F; private final float scaleOffsetChange = 0.125F; @@ -44,31 +44,31 @@ public DisplayBlockEditScreen(DisplayBlockEntity displayBlock) { public void init() { super.init(); - if (this.client != null) { - this.scaleField = new TextFieldWidget(this.client.textRenderer, 90, 10, 60, 20, Text.empty()); - this.scaleField.setText(String.valueOf(this.displayBlock.getScale().x())); - this.scaleField.setChangedListener(string -> { + if (this.minecraft != null) { + this.scaleField = new EditBox(this.minecraft.font, 90, 10, 60, 20, Component.empty()); + this.scaleField.setValue(String.valueOf(this.displayBlock.getScale().x())); + this.scaleField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) { this.displayBlock.setScale(new Vector3f(parsed, parsed, parsed)); editDisplayBlock(); } }); - this.decreaseSize = ButtonWidget.builder(Text.literal("-"), action -> { + this.decreaseSize = Button.builder(Component.literal("-"), action -> { this.displayBlock.getScale().sub(scaleOffsetChange, scaleOffsetChange, scaleOffsetChange); editDisplayBlock(); - this.scaleField.setText(String.valueOf(this.displayBlock.getScale().x())); - }).dimensions(90 + 60 + 5, 10, 20, 20).build(); + this.scaleField.setValue(String.valueOf(this.displayBlock.getScale().x())); + }).bounds(90 + 60 + 5, 10, 20, 20).build(); - this.increaseSize = ButtonWidget.builder(Text.literal("+"), action -> { + this.increaseSize = Button.builder(Component.literal("+"), action -> { this.displayBlock.getScale().add(scaleOffsetChange, scaleOffsetChange, scaleOffsetChange); editDisplayBlock(); - this.scaleField.setText(String.valueOf(this.displayBlock.getScale().x())); - }).dimensions(90 + 60 + 5 + 20, 10, 20, 20).build(); + this.scaleField.setValue(String.valueOf(this.displayBlock.getScale().x())); + }).bounds(90 + 60 + 5 + 20, 10, 20, 20).build(); - this.xOffsetField = new TextFieldWidget(this.client.textRenderer, 90, 40, 60, 20, Text.empty()); - this.xOffsetField.setText(String.valueOf(this.displayBlock.getOffset().x())); - this.xOffsetField.setChangedListener(string -> { + this.xOffsetField = new EditBox(this.minecraft.font, 90, 40, 60, 20, Component.empty()); + this.xOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().x())); + this.xOffsetField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) { Vector3f offset = this.displayBlock.getOffset(); offset.x = parsed; @@ -77,21 +77,21 @@ public void init() { } }); - this.decreaseXOffset = ButtonWidget.builder(Text.literal("-"), action -> { + this.decreaseXOffset = Button.builder(Component.literal("-"), action -> { this.displayBlock.getOffset().sub(scaleOffsetChange, 0, 0); editDisplayBlock(); - this.xOffsetField.setText(String.valueOf(this.displayBlock.getOffset().x())); - }).dimensions(90 + 60 + 5, 40, 20, 20).build(); + this.xOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().x())); + }).bounds(90 + 60 + 5, 40, 20, 20).build(); - this.increaseXOffset = ButtonWidget.builder(Text.literal("+"), action -> { + this.increaseXOffset = Button.builder(Component.literal("+"), action -> { this.displayBlock.getOffset().add(scaleOffsetChange, 0, 0); editDisplayBlock(); - this.xOffsetField.setText(String.valueOf(this.displayBlock.getOffset().x())); - }).dimensions(90 + 60 + 5 + 20, 40, 20, 20).build(); + this.xOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().x())); + }).bounds(90 + 60 + 5 + 20, 40, 20, 20).build(); - this.yOffsetField = new TextFieldWidget(this.client.textRenderer, 90, 70, 60, 20, Text.empty()); - this.yOffsetField.setText(String.valueOf(this.displayBlock.getOffset().y())); - this.yOffsetField.setChangedListener(string -> { + this.yOffsetField = new EditBox(this.minecraft.font, 90, 70, 60, 20, Component.empty()); + this.yOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().y())); + this.yOffsetField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) { Vector3f offset = this.displayBlock.getOffset(); offset.y = parsed; @@ -100,21 +100,21 @@ public void init() { } }); - this.decreaseYOffset = ButtonWidget.builder(Text.literal("-"), action -> { + this.decreaseYOffset = Button.builder(Component.literal("-"), action -> { this.displayBlock.getOffset().sub(0, scaleOffsetChange, 0); editDisplayBlock(); - this.yOffsetField.setText(String.valueOf(this.displayBlock.getOffset().y())); - }).dimensions(90 + 60 + 5, 70, 20, 20).build(); + this.yOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().y())); + }).bounds(90 + 60 + 5, 70, 20, 20).build(); - this.increaseYOffset = ButtonWidget.builder(Text.literal("+"), action -> { + this.increaseYOffset = Button.builder(Component.literal("+"), action -> { this.displayBlock.getOffset().add(0, scaleOffsetChange, 0); editDisplayBlock(); - this.yOffsetField.setText(String.valueOf(this.displayBlock.getOffset().y())); - }).dimensions(90 + 60 + 5 + 20, 70, 20, 20).build(); + this.yOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().y())); + }).bounds(90 + 60 + 5 + 20, 70, 20, 20).build(); - this.zOffsetField = new TextFieldWidget(this.client.textRenderer, 90, 100, 60, 20, Text.empty()); - this.zOffsetField.setText(String.valueOf(this.displayBlock.getOffset().z())); - this.zOffsetField.setChangedListener(string -> { + this.zOffsetField = new EditBox(this.minecraft.font, 90, 100, 60, 20, Component.empty()); + this.zOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().z())); + this.zOffsetField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) { Vector3f offset = this.displayBlock.getOffset(); offset.z = parsed; @@ -123,90 +123,90 @@ public void init() { } }); - this.decreaseZOffset = ButtonWidget.builder(Text.literal("-"), action -> { + this.decreaseZOffset = Button.builder(Component.literal("-"), action -> { this.displayBlock.getOffset().sub(0, 0, scaleOffsetChange); editDisplayBlock(); - this.zOffsetField.setText(String.valueOf(this.displayBlock.getOffset().z())); - }).dimensions(90 + 60 + 5, 100, 20, 20).build(); + this.zOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().z())); + }).bounds(90 + 60 + 5, 100, 20, 20).build(); - this.increaseZOffset = ButtonWidget.builder(Text.literal("+"), action -> { + this.increaseZOffset = Button.builder(Component.literal("+"), action -> { this.displayBlock.getOffset().add(0, 0, scaleOffsetChange); editDisplayBlock(); - this.zOffsetField.setText(String.valueOf(this.displayBlock.getOffset().z())); - }).dimensions(90 + 60 + 5 + 20, 100, 20, 20).build(); + this.zOffsetField.setValue(String.valueOf(this.displayBlock.getOffset().z())); + }).bounds(90 + 60 + 5 + 20, 100, 20, 20).build(); - this.pitchField = new TextFieldWidget(this.client.textRenderer, 90, 130, 60, 20, Text.empty()); - this.pitchField.setText(String.valueOf(this.displayBlock.getPitch())); - this.pitchField.setChangedListener(string -> { + this.pitchField = new EditBox(this.minecraft.font, 90, 130, 60, 20, Component.empty()); + this.pitchField.setValue(String.valueOf(this.displayBlock.getPitch())); + this.pitchField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) { this.displayBlock.setPitch(parsed); editDisplayBlock(); } }); - this.decreasePitch = ButtonWidget.builder(Text.literal("-"), action -> { + this.decreasePitch = Button.builder(Component.literal("-"), action -> { this.displayBlock.setPitch(this.displayBlock.getPitch() - pitchYawChange); editDisplayBlock(); - this.pitchField.setText(String.valueOf(this.displayBlock.getPitch())); - }).dimensions(90 + 60 + 5, 130, 20, 20).build(); + this.pitchField.setValue(String.valueOf(this.displayBlock.getPitch())); + }).bounds(90 + 60 + 5, 130, 20, 20).build(); - this.increasePitch = ButtonWidget.builder(Text.literal("+"), action -> { + this.increasePitch = Button.builder(Component.literal("+"), action -> { this.displayBlock.setPitch(this.displayBlock.getPitch() + pitchYawChange); editDisplayBlock(); - this.pitchField.setText(String.valueOf(this.displayBlock.getPitch())); - }).dimensions(90 + 60 + 5 + 20, 130, 20, 20).build(); + this.pitchField.setValue(String.valueOf(this.displayBlock.getPitch())); + }).bounds(90 + 60 + 5 + 20, 130, 20, 20).build(); - this.yawField = new TextFieldWidget(this.client.textRenderer, 90, 160, 60, 20, Text.empty()); - this.yawField.setText(String.valueOf(this.displayBlock.getYaw())); - this.yawField.setChangedListener(string -> { + this.yawField = new EditBox(this.minecraft.font, 90, 160, 60, 20, Component.empty()); + this.yawField.setValue(String.valueOf(this.displayBlock.getYaw())); + this.yawField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) { this.displayBlock.setYaw(parsed); editDisplayBlock(); } }); - this.decreaseYaw = ButtonWidget.builder(Text.literal("-"), action -> { + this.decreaseYaw = Button.builder(Component.literal("-"), action -> { this.displayBlock.setYaw(this.displayBlock.getYaw() - pitchYawChange); editDisplayBlock(); - this.yawField.setText(String.valueOf(this.displayBlock.getYaw())); - }).dimensions(90 + 60 + 5, 160, 20, 20).build(); + this.yawField.setValue(String.valueOf(this.displayBlock.getYaw())); + }).bounds(90 + 60 + 5, 160, 20, 20).build(); - this.increaseYaw = ButtonWidget.builder(Text.literal("+"), action -> { + this.increaseYaw = Button.builder(Component.literal("+"), action -> { this.displayBlock.setYaw(this.displayBlock.getYaw() + pitchYawChange); editDisplayBlock(); - this.yawField.setText(String.valueOf(this.displayBlock.getYaw())); - }).dimensions(90 + 60 + 5 + 20, 160, 20, 20).build(); - - this.addDrawableChild(this.scaleField); - this.addDrawableChild(this.xOffsetField); - this.addDrawableChild(this.yOffsetField); - this.addDrawableChild(this.zOffsetField); - this.addDrawableChild(this.pitchField); - this.addDrawableChild(this.yawField); - this.addDrawableChild(this.decreaseSize); - this.addDrawableChild(this.increaseSize); - this.addDrawableChild(this.decreaseXOffset); - this.addDrawableChild(this.increaseXOffset); - this.addDrawableChild(this.decreaseYOffset); - this.addDrawableChild(this.increaseYOffset); - this.addDrawableChild(this.decreaseZOffset); - this.addDrawableChild(this.increaseZOffset); - this.addDrawableChild(this.decreasePitch); - this.addDrawableChild(this.increasePitch); - this.addDrawableChild(this.decreaseYaw); - this.addDrawableChild(this.increaseYaw); + this.yawField.setValue(String.valueOf(this.displayBlock.getYaw())); + }).bounds(90 + 60 + 5 + 20, 160, 20, 20).build(); + + this.addRenderableWidget(this.scaleField); + this.addRenderableWidget(this.xOffsetField); + this.addRenderableWidget(this.yOffsetField); + this.addRenderableWidget(this.zOffsetField); + this.addRenderableWidget(this.pitchField); + this.addRenderableWidget(this.yawField); + this.addRenderableWidget(this.decreaseSize); + this.addRenderableWidget(this.increaseSize); + this.addRenderableWidget(this.decreaseXOffset); + this.addRenderableWidget(this.increaseXOffset); + this.addRenderableWidget(this.decreaseYOffset); + this.addRenderableWidget(this.increaseYOffset); + this.addRenderableWidget(this.decreaseZOffset); + this.addRenderableWidget(this.increaseZOffset); + this.addRenderableWidget(this.decreasePitch); + this.addRenderableWidget(this.increasePitch); + this.addRenderableWidget(this.decreaseYaw); + this.addRenderableWidget(this.increaseYaw); } } - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (this.client != null) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { + if (this.minecraft != null) { super.render(context, mouseX, mouseY, delta); - context.drawTextWithShadow(client.textRenderer, Text.translatable("gui.glowcase.scale_label"), 20, 17, 0xFFFFFFFF); - context.drawTextWithShadow(client.textRenderer, Text.translatable("gui.glowcase.x_offset_label"), 20, 47, 0xFFFFFFFF); - context.drawTextWithShadow(client.textRenderer, Text.translatable("gui.glowcase.y_offset_label"), 20, 77, 0xFFFFFFFF); - context.drawTextWithShadow(client.textRenderer, Text.translatable("gui.glowcase.z_offset_label"), 20, 107, 0xFFFFFFFF); - context.drawTextWithShadow(client.textRenderer, Text.translatable("gui.glowcase.pitch_value"), 20, 137, 0xFFFFFFFF); - context.drawTextWithShadow(client.textRenderer, Text.translatable("gui.glowcase.yaw_value"), 20, 167, 0xFFFFFFFF); + context.drawString(minecraft.font, Component.translatable("gui.glowcase.scale_label"), 20, 17, 0xFFFFFFFF); + context.drawString(minecraft.font, Component.translatable("gui.glowcase.x_offset_label"), 20, 47, 0xFFFFFFFF); + context.drawString(minecraft.font, Component.translatable("gui.glowcase.y_offset_label"), 20, 77, 0xFFFFFFFF); + context.drawString(minecraft.font, Component.translatable("gui.glowcase.z_offset_label"), 20, 107, 0xFFFFFFFF); + context.drawString(minecraft.font, Component.translatable("gui.glowcase.pitch_value"), 20, 137, 0xFFFFFFFF); + context.drawString(minecraft.font, Component.translatable("gui.glowcase.yaw_value"), 20, 167, 0xFFFFFFFF); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/GlowcaseScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/GlowcaseScreen.java index 81fc0d5f..20774443 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/GlowcaseScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/GlowcaseScreen.java @@ -1,22 +1,22 @@ package dev.hephaestus.glowcase.client.gui.screen.ingame; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.text.Text; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; public abstract class GlowcaseScreen extends Screen { protected GlowcaseScreen() { - super(Text.empty()); + super(Component.empty()); } @Override - public void renderBackground(DrawContext context, int mouseX, int mouseY, float deltaTicks) { - this.renderInGameBackground(context); - context.applyBlur(); + public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float deltaTicks) { + this.renderTransparentBackground(context); + context.blurBeforeThisStratum(); } @Override - public boolean shouldPause() { + public boolean isPauseScreen() { return false; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/HyperlinkBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/HyperlinkBlockEditScreen.java index 13d7b2eb..f445f254 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/HyperlinkBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/HyperlinkBlockEditScreen.java @@ -3,15 +3,16 @@ import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditHyperlinkBlock; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.Text; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.network.chat.Component; import org.lwjgl.glfw.GLFW; public class HyperlinkBlockEditScreen extends GlowcaseScreen { private final HyperlinkBlockEntity hyperlinkBlockEntity; - private TextFieldWidget titleEntryWidget; - private TextFieldWidget urlEntryWidget; + private EditBox titleEntryWidget; + private EditBox urlEntryWidget; public HyperlinkBlockEditScreen(HyperlinkBlockEntity hyperlinkBlockEntity) { this.hyperlinkBlockEntity = hyperlinkBlockEntity; @@ -21,41 +22,42 @@ public HyperlinkBlockEditScreen(HyperlinkBlockEntity hyperlinkBlockEntity) { public void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; - this.titleEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 10, height / 2 - 30, 8 * width / 10, 20, Text.empty()); + this.titleEntryWidget = new EditBox(this.minecraft.font, width / 10, height / 2 - 30, 8 * width / 10, 20, Component.empty()); this.titleEntryWidget.setMaxLength(HyperlinkBlockEntity.TITLE_MAX_LENGTH); - this.titleEntryWidget.setText(this.hyperlinkBlockEntity.getTitle()); - this.titleEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.title")); + this.titleEntryWidget.setValue(this.hyperlinkBlockEntity.getTitle()); + this.titleEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.title")); - this.urlEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 10, height / 2 + 10, 8 * width / 10, 20, Text.empty()); + this.urlEntryWidget = new EditBox(this.minecraft.font, width / 10, height / 2 + 10, 8 * width / 10, 20, Component.empty()); this.urlEntryWidget.setMaxLength(HyperlinkBlockEntity.URL_MAX_LENGTH); - this.urlEntryWidget.setText(this.hyperlinkBlockEntity.getUrl()); - this.urlEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.url")); + this.urlEntryWidget.setValue(this.hyperlinkBlockEntity.getUrl()); + this.urlEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.url")); - this.addDrawableChild(this.titleEntryWidget); - this.addDrawableChild(this.urlEntryWidget); + this.addRenderableWidget(this.titleEntryWidget); + this.addRenderableWidget(this.urlEntryWidget); } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + public boolean keyPressed(KeyEvent event) { + int keyCode = event.key(); if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER || keyCode == GLFW.GLFW_KEY_ESCAPE) { - this.close(); + this.onClose(); return true; - } else if (this.titleEntryWidget.isActive()) { - return this.titleEntryWidget.keyPressed(keyCode, scanCode, modifiers); - } else if (this.urlEntryWidget.isActive()) { - return this.urlEntryWidget.keyPressed(keyCode, scanCode, modifiers); + } else if (this.titleEntryWidget.canConsumeInput()) { + return this.titleEntryWidget.keyPressed(event); + } else if (this.urlEntryWidget.canConsumeInput()) { + return this.urlEntryWidget.keyPressed(event); } else { return false; } } @Override - public void close() { - hyperlinkBlockEntity.setUrl(urlEntryWidget.getText()); - hyperlinkBlockEntity.setTitle(titleEntryWidget.getText()); + public void onClose() { + hyperlinkBlockEntity.setUrl(urlEntryWidget.getValue()); + hyperlinkBlockEntity.setTitle(titleEntryWidget.getValue()); C2SEditHyperlinkBlock.of(hyperlinkBlockEntity).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemAcceptorBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemAcceptorBlockEditScreen.java index f1428860..01b34139 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemAcceptorBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemAcceptorBlockEditScreen.java @@ -4,19 +4,19 @@ import dev.hephaestus.glowcase.block.entity.ItemAcceptorBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditItemAcceptorBlock; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.gui.widget.TextWidget; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; public class ItemAcceptorBlockEditScreen extends GlowcaseScreen { private final ItemAcceptorBlockEntity itemAcceptorBlockEntity; - private TextFieldWidget itemWidget; - private TextFieldWidget countWidget; - private TextFieldWidget pulseWidget; - private ButtonWidget outputDirectionToggle; + private EditBox itemWidget; + private EditBox countWidget; + private EditBox pulseWidget; + private Button outputDirectionToggle; public ItemAcceptorBlockEditScreen(ItemAcceptorBlockEntity itemAcceptorBlockEntity) { this.itemAcceptorBlockEntity = itemAcceptorBlockEntity; @@ -26,49 +26,52 @@ public ItemAcceptorBlockEditScreen(ItemAcceptorBlockEntity itemAcceptorBlockEnti public void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; Identifier item = this.itemAcceptorBlockEntity.getItem(); - this.itemWidget = new TextFieldWidget(this.textRenderer, width / 2 - 100, height / 2 - 25, 150, 20, Text.empty()); + this.itemWidget = new EditBox(this.font, width / 2 - 100, height / 2 - 25, 150, 20, Component.empty()); this.itemWidget.setMaxLength(128); - if (!item.equals(Identifier.ofVanilla("air"))) { - this.itemWidget.setText((this.itemAcceptorBlockEntity.isItemTag ? "#" : "") + item); + if (!item.equals(Identifier.withDefaultNamespace("air"))) { + this.itemWidget.setValue((this.itemAcceptorBlockEntity.isItemTag ? "#" : "") + item); } - this.itemWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.item_or_tag")); - this.itemWidget.setTextPredicate(s -> s.matches("#?[a-z0-9_.-]*:?[a-z0-9_./-]*")); + this.itemWidget.setHint(TextUtils.placeholder("gui.glowcase.item_or_tag")); +//FIXME 26.1 + // this.itemWidget.setFilter(s -> s.matches("#?[a-z0-9_.-]*:?[a-z0-9_./-]*")); - this.countWidget = new TextFieldWidget(this.textRenderer, width / 2 + 60, height / 2 - 25, 40, 20, Text.empty()); - this.countWidget.setText(String.valueOf(this.itemAcceptorBlockEntity.count)); - this.countWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.count")); - this.countWidget.setTextPredicate(s -> s.matches("\\d*")); + this.countWidget = new EditBox(this.font, width / 2 + 60, height / 2 - 25, 40, 20, Component.empty()); + this.countWidget.setValue(String.valueOf(this.itemAcceptorBlockEntity.count)); + this.countWidget.setHint(TextUtils.placeholder("gui.glowcase.count")); + //FIXME 26.1 +// this.countWidget.setFilter(s -> s.matches("\\d*")); - this.outputDirectionToggle = ButtonWidget.builder(Text.translatable("gui.glowcase.output_direction", this.itemAcceptorBlockEntity.outputDirection.toString()), action -> { + this.outputDirectionToggle = Button.builder(Component.translatable("gui.glowcase.output_direction", this.itemAcceptorBlockEntity.outputDirection.toString()), action -> { switch (itemAcceptorBlockEntity.outputDirection) { case TOP -> itemAcceptorBlockEntity.outputDirection = ItemAcceptorBlockEntity.OutputDirection.BACK; case BACK -> itemAcceptorBlockEntity.outputDirection = ItemAcceptorBlockEntity.OutputDirection.BOTTOM; case BOTTOM -> itemAcceptorBlockEntity.outputDirection = ItemAcceptorBlockEntity.OutputDirection.TOP; } - this.outputDirectionToggle.setMessage(Text.translatable("gui.glowcase.output_direction", this.itemAcceptorBlockEntity.outputDirection.toString())); - }).dimensions(width / 2 - 100, height / 2 + 5, 150, 20).build(); - - this.pulseWidget = new TextFieldWidget(this.textRenderer, width / 2 + 60, height / 2 + 5, 40, 20, Text.empty()); - this.pulseWidget.setText(String.valueOf(this.itemAcceptorBlockEntity.pulse)); - this.pulseWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.pulse")); - this.pulseWidget.setTextPredicate(s -> s.matches("\\d*")); - - this.addDrawableChild(this.itemWidget); - this.addDrawableChild(this.countWidget); - this.addDrawableChild(this.outputDirectionToggle); - this.addDrawableChild(this.pulseWidget); - this.addDrawableChild(new TextWidget(width / 2 + 50, height / 2 - 25, 10, 20, Text.of("x"), textRenderer)); - this.addDrawableChild(new TextWidget(width / 2 + 50, height / 2 + 5, 10, 20, Text.of("x"), textRenderer)); + this.outputDirectionToggle.setMessage(Component.translatable("gui.glowcase.output_direction", this.itemAcceptorBlockEntity.outputDirection.toString())); + }).bounds(width / 2 - 100, height / 2 + 5, 150, 20).build(); + + this.pulseWidget = new EditBox(this.font, width / 2 + 60, height / 2 + 5, 40, 20, Component.empty()); + this.pulseWidget.setValue(String.valueOf(this.itemAcceptorBlockEntity.pulse)); + this.pulseWidget.setHint(TextUtils.placeholder("gui.glowcase.pulse")); +//FIXME 26.1 + // this.pulseWidget.setFilter(s -> s.matches("\\d*")); + + this.addRenderableWidget(this.itemWidget); + this.addRenderableWidget(this.countWidget); + this.addRenderableWidget(this.outputDirectionToggle); + this.addRenderableWidget(this.pulseWidget); + this.addRenderableWidget(new StringWidget(width / 2 + 50, height / 2 - 25, 10, 20, Component.nullToEmpty("x"), font)); + this.addRenderableWidget(new StringWidget(width / 2 + 50, height / 2 + 5, 10, 20, Component.nullToEmpty("x"), font)); } @Override - public void close() { - String text = itemWidget.getText(); + public void onClose() { + String text = itemWidget.getValue(); boolean isItemTag = text.startsWith("#"); if (isItemTag) { text = text.substring(1); @@ -78,18 +81,18 @@ public void close() { this.itemAcceptorBlockEntity.setItem(id); this.itemAcceptorBlockEntity.isItemTag = isItemTag; } else { - this.itemAcceptorBlockEntity.setItem(Identifier.ofVanilla("air")); + this.itemAcceptorBlockEntity.setItem(Identifier.withDefaultNamespace("air")); } - if (Ints.tryParse(countWidget.getText()) instanceof Integer integer) { + if (Ints.tryParse(countWidget.getValue()) instanceof Integer integer) { this.itemAcceptorBlockEntity.count = Math.max(0, integer); } - if (Ints.tryParse(pulseWidget.getText()) instanceof Integer integer) { + if (Ints.tryParse(pulseWidget.getValue()) instanceof Integer integer) { this.itemAcceptorBlockEntity.pulse = Math.max(0, integer); } C2SEditItemAcceptorBlock.of(this.itemAcceptorBlockEntity).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemDisplayEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemDisplayEditScreen.java index f802ad96..02f10716 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemDisplayEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemDisplayEditScreen.java @@ -2,11 +2,11 @@ import dev.hephaestus.glowcase.block.entity.DisplayBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditItemDisplayBlock; -import net.minecraft.client.gui.widget.CheckboxWidget; -import net.minecraft.text.Text; +import net.minecraft.client.gui.components.Checkbox; +import net.minecraft.network.chat.Component; public class ItemDisplayEditScreen extends DisplayBlockEditScreen { - private CheckboxWidget renderAsBlockWidget; + private Checkbox renderAsBlockWidget; public ItemDisplayEditScreen(DisplayBlockEntity displayBlock) { super(displayBlock); @@ -16,13 +16,13 @@ public ItemDisplayEditScreen(DisplayBlockEntity displayBlock) { public void init() { super.init(); - this.renderAsBlockWidget = CheckboxWidget.builder(Text.translatable("gui.glowcase.render_as_block"), this.client.textRenderer) - .checked(this.displayBlock.getRenderAsBlock()) - .callback((checkbox, checked) -> this.displayBlock.setRenderAsBlock(checked)) + this.renderAsBlockWidget = Checkbox.builder(Component.translatable("gui.glowcase.render_as_block"), this.minecraft.font) + .selected(this.displayBlock.getRenderAsBlock()) + .onValueChange((checkbox, checked) -> this.displayBlock.setRenderAsBlock(checked)) .pos(20, 197) .build(); - this.addDrawableChild(this.renderAsBlockWidget); + this.addRenderableWidget(this.renderAsBlockWidget); } @Override diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemProviderBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemProviderBlockEditScreen.java index 5fc5989a..2b2cab64 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemProviderBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ItemProviderBlockEditScreen.java @@ -4,17 +4,17 @@ import dev.hephaestus.glowcase.block.entity.ItemProviderBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditItemProviderBlock; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.gui.widget.TextWidget; -import net.minecraft.text.Text; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.network.chat.Component; public class ItemProviderBlockEditScreen extends GlowcaseScreen { private final ItemProviderBlockEntity providerBlock; - private ButtonWidget givesItemButton; - private TextFieldWidget cooldownWidget; - private TextWidget secondsLabel; + private Button givesItemButton; + private EditBox cooldownWidget; + private StringWidget secondsLabel; public ItemProviderBlockEditScreen(ItemProviderBlockEntity providerBlock) { this.providerBlock = providerBlock; } @@ -23,39 +23,40 @@ public ItemProviderBlockEditScreen(ItemProviderBlockEntity providerBlock) { public void init() { super.init(); - if (this.client != null) { - this.givesItemButton = ButtonWidget.builder(Text.stringifiedTranslatable("gui.glowcase.gives_item", this.providerBlock.getGivesItem()), (action) -> { + if (this.minecraft != null) { + this.givesItemButton = Button.builder(Component.translatableEscape("gui.glowcase.gives_item", this.providerBlock.getGivesItem()), (action) -> { this.providerBlock.cycleGiveType(); - this.givesItemButton.setMessage(Text.stringifiedTranslatable("gui.glowcase.gives_item", this.providerBlock.getGivesItem())); + this.givesItemButton.setMessage(Component.translatableEscape("gui.glowcase.gives_item", this.providerBlock.getGivesItem())); this.cooldownWidget.setVisible(this.providerBlock.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED); this.secondsLabel.visible = this.providerBlock.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED; - if (this.providerBlock.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED && (this.cooldownWidget.getText().isBlank() || this.cooldownWidget.getText().equals("0"))) this.cooldownWidget.setText(String.valueOf(60)); - }).dimensions(width / 2 - 75, height / 2 - 25, 150, 20).build(); - - this.cooldownWidget = new TextFieldWidget(this.textRenderer, width / 2 - 30, height / 2 + 5, 60, 20, Text.empty()); - this.cooldownWidget.setText(this.providerBlock.cooldown == 0 ? "" : String.valueOf(this.providerBlock.cooldown)); - this.cooldownWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.cooldown")); - this.cooldownWidget.setTextPredicate(s -> s.matches("\\d*")); + if (this.providerBlock.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED && (this.cooldownWidget.getValue().isBlank() || this.cooldownWidget.getValue().equals("0"))) this.cooldownWidget.setValue(String.valueOf(60)); + }).bounds(width / 2 - 75, height / 2 - 25, 150, 20).build(); + + this.cooldownWidget = new EditBox(this.font, width / 2 - 30, height / 2 + 5, 60, 20, Component.empty()); + this.cooldownWidget.setValue(this.providerBlock.cooldown == 0 ? "" : String.valueOf(this.providerBlock.cooldown)); + this.cooldownWidget.setHint(TextUtils.placeholder("gui.glowcase.cooldown")); + //FIXME 26.1 +// this.cooldownWidget.setFilter(s -> s.matches("\\d*")); this.cooldownWidget.setVisible(this.providerBlock.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED); - this.secondsLabel = new TextWidget(width / 2 + 30, height / 2 + 5, 10, 20, Text.of("s"), this.textRenderer); + this.secondsLabel = new StringWidget(width / 2 + 30, height / 2 + 5, 10, 20, Component.nullToEmpty("s"), this.font); this.secondsLabel.visible = this.providerBlock.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED; - this.addDrawableChild(this.givesItemButton); - this.addDrawableChild(this.cooldownWidget); - this.addDrawableChild(this.secondsLabel); + this.addRenderableWidget(this.givesItemButton); + this.addRenderableWidget(this.cooldownWidget); + this.addRenderableWidget(this.secondsLabel); } } @Override - public void close() { + public void onClose() { if (this.providerBlock.getGivesItem() != ItemProviderBlockEntity.GivesItem.TIMED) { this.providerBlock.cooldown = 0; - } else if (Longs.tryParse(cooldownWidget.getText()) instanceof Long l) { + } else if (Longs.tryParse(cooldownWidget.getValue()) instanceof Long l) { this.providerBlock.cooldown = Math.clamp(l, 0, 172800000 /* 48 Hours */); } C2SEditItemProviderBlock.of(providerBlock).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/NoteEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/NoteEditScreen.java index fc638712..4eb38cdd 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/NoteEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/NoteEditScreen.java @@ -9,24 +9,27 @@ import eu.pb4.placeholders.api.ParserContext; import eu.pb4.placeholders.api.parsers.NodeParser; import eu.pb4.placeholders.api.parsers.TagParser; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.util.SelectionManager; -import net.minecraft.item.ItemStack; -import net.minecraft.text.StringVisitable; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.util.Language; -import net.minecraft.util.math.MathHelper; +import net.minecraft.client.input.CharacterEvent; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; import org.lwjgl.glfw.GLFW; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.font.TextFieldHelper; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.locale.Language; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FormattedText; +import net.minecraft.network.chat.Style; +import net.minecraft.resources.Identifier; +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; //TODO: multi-character selection at some point? it may be a bit complex but it'd be nice public class NoteEditScreen extends TextEditorScreen { @@ -44,32 +47,32 @@ public class NoteEditScreen extends TextEditorScreen { private static final int TXT_OFF_Y = 12; private static final int TXT_X_PADDING = 15 * 2; - private static final Text ARROW_LEFT_SYMBOL = Text.literal("«"); - private static final Text ARROW_RIGHT_SYMBOL = Text.literal("»"); + private static final Component ARROW_LEFT_SYMBOL = Component.literal("«"); + private static final Component ARROW_RIGHT_SYMBOL = Component.literal("»"); private int editing_line_offset = 0; - private final List lines; + private final List lines; private String title = ""; private String author = ""; private NoteComponent.Alignment textAlignment; public static final NodeParser PARSER = TagParser.DEFAULT; - private SelectionManager selectionManager; + private TextFieldHelper selectionManager; private int currentRow; private long ticksSinceOpened = 0; private boolean signing = false; private boolean finalizing = false; - private List signing_text; + private List signing_text; private ColorPickerWidget colorPickerWidget; - private ButtonWidget doneButton; - private ButtonWidget signButton; - private ButtonWidget changeAlignment; + private Button doneButton; + private Button signButton; + private Button changeAlignment; public NoteEditScreen(ItemStack stack) { - if (stack.contains(Glowcase.NOTE_COMPONENT.get())) { + if (stack.has(Glowcase.NOTE_COMPONENT.get())) { // Load data NoteComponent note = stack.get(Glowcase.NOTE_COMPONENT.get()); assert note != null; @@ -77,7 +80,7 @@ public NoteEditScreen(ItemStack stack) { lines = new ArrayList<>(); lines.addAll(note.lines()); for (int i = 0; i < (NoteComponent.LINES_LIMIT - note.lines().size()); i++) - lines.add(Text.literal("")); + lines.add(Component.literal("")); textAlignment = note.alignment(); } else { @@ -85,7 +88,7 @@ public NoteEditScreen(ItemStack stack) { lines = new ArrayList<>(); for (int i = 0; i < NoteComponent.LINES_LIMIT; i++) - lines.add(Text.literal("")); + lines.add(Component.literal("")); textAlignment = NoteComponent.Alignment.LEFT; } @@ -94,9 +97,9 @@ public NoteEditScreen(ItemStack stack) { @Override protected void init() { super.init(); - if (client == null) return; + if (minecraft == null) return; - selectionManager = new SelectionManager( + selectionManager = new TextFieldHelper( () -> signing ? (currentRow == 6 ? title : author) : getRawLine(currentRow), (string) -> { if (signing) { @@ -107,36 +110,36 @@ protected void init() { } else setRawLine(currentRow, string); }, - SelectionManager.makeClipboardGetter(client), - SelectionManager.makeClipboardSetter(client), + TextFieldHelper.createClipboardGetter(minecraft), + TextFieldHelper.createClipboardSetter(minecraft), (string) -> true); // Setup Signing Screen signing_text = new ArrayList<>(); //noinspection unchecked - Pair[] lines = new Pair[]{ - new Pair<>(2, Text.translatable("gui.glowcase.note.signing")), - new Pair<>(3, Text.translatable("gui.glowcase.note.warning")), - new Pair<>(1, Text.literal("")), - new Pair<>(1, Text.translatable("gui.glowcase.note.title")), - new Pair<>(1, Text.translatable("gui.glowcase.note.author")), - new Pair<>(1, Text.literal("")), - new Pair<>(1, Text.translatable("gui.glowcase.note.required").setStyle(Style.EMPTY.withColor(Formatting.RED))), + Pair[] lines = new Pair[]{ + new Pair<>(2, Component.translatable("gui.glowcase.note.signing")), + new Pair<>(3, Component.translatable("gui.glowcase.note.warning")), + new Pair<>(1, Component.literal("")), + new Pair<>(1, Component.translatable("gui.glowcase.note.title")), + new Pair<>(1, Component.translatable("gui.glowcase.note.author")), + new Pair<>(1, Component.literal("")), + new Pair<>(1, Component.translatable("gui.glowcase.note.required").setStyle(Style.EMPTY.withColor(ChatFormatting.RED))), }; - for (Pair section : lines) { + for (Pair section : lines) { int height = section.getFirst(); - List texts = textRenderer.getTextHandler().wrapLines(section.getSecond(), BG_WIDTH - TXT_X_PADDING, Style.EMPTY); + List texts = font.getSplitter().splitLines(section.getSecond(), BG_WIDTH - TXT_X_PADDING, Style.EMPTY); for (int i = 0; i < height; i++) { if (i + 1 <= texts.size()) { - StringVisitable text = texts.get(i); + FormattedText text = texts.get(i); if (i == (height - 1) && texts.size() > height) - text = ensureBounds(textRenderer, text); + text = ensureBounds(font, text); signing_text.add(text); } else { - signing_text.add(Text.empty()); + signing_text.add(Component.empty()); } } } @@ -144,21 +147,21 @@ protected void init() { // Widgets int offset = 7; - this.changeAlignment = ButtonWidget.builder(Text.stringifiedTranslatable("gui.glowcase.alignment", textAlignment), action -> { + this.changeAlignment = Button.builder(Component.translatableEscape("gui.glowcase.alignment", textAlignment), action -> { switch (textAlignment) { case LEFT -> textAlignment = NoteComponent.Alignment.CENTER; case CENTER -> textAlignment = NoteComponent.Alignment.RIGHT; case RIGHT -> textAlignment = NoteComponent.Alignment.LEFT; } - this.changeAlignment.setMessage(Text.stringifiedTranslatable("gui.glowcase.alignment", textAlignment)); - }).dimensions(width / 2 - BG_WIDTH / 2, height / 2 - BG_HEIGHT / 2 - offset - 20, BG_WIDTH / 12 * 6 - 3 - 7, 20).build(); + this.changeAlignment.setMessage(Component.translatableEscape("gui.glowcase.alignment", textAlignment)); + }).bounds(width / 2 - BG_WIDTH / 2, height / 2 - BG_HEIGHT / 2 - offset - 20, BG_WIDTH / 12 * 6 - 3 - 7, 20).build(); - signButton = ButtonWidget.builder(Text.translatable("book.signButton"), action -> { + signButton = Button.builder(Component.translatable("book.signButton"), action -> { if (!signing) { signing = true; - doneButton.setMessage(Text.translatable("gui.cancel")); - signButton.setMessage(Text.translatable("book.finalizeButton")); + doneButton.setMessage(Component.translatable("gui.cancel")); + signButton.setMessage(Component.translatable("book.finalizeButton")); signButton.active = false; changeAlignment.active = false; toggleWidgets(false); @@ -168,41 +171,41 @@ protected void init() { currentRow = 6; } else { finalizing = true; - close(); + onClose(); } - }).dimensions(width / 2 - BG_WIDTH / 2, height / 2 + BG_HEIGHT / 2 + offset, BG_WIDTH / 2 - 3, 20).build(); - doneButton = ButtonWidget.builder(Text.translatable("gui.done"), action -> { + }).bounds(width / 2 - BG_WIDTH / 2, height / 2 + BG_HEIGHT / 2 + offset, BG_WIDTH / 2 - 3, 20).build(); + doneButton = Button.builder(Component.translatable("gui.done"), action -> { if (signing) { signing = false; - doneButton.setMessage(Text.translatable("gui.done")); - signButton.setMessage(Text.translatable("book.signButton")); + doneButton.setMessage(Component.translatable("gui.done")); + signButton.setMessage(Component.translatable("book.signButton")); signButton.active = true; changeAlignment.active = true; toggleWidgets(true); } else - close(); - }).dimensions(width / 2 + BG_WIDTH / 2 - (BG_WIDTH / 2 - 3), height / 2 + BG_HEIGHT / 2 + offset, BG_WIDTH / 2 - 3, 20).build(); + onClose(); + }).bounds(width / 2 + BG_WIDTH / 2 - (BG_WIDTH / 2 - 3), height / 2 + BG_HEIGHT / 2 + offset, BG_WIDTH / 2 - 3, 20).build(); this.colorPickerWidget = ColorPickerWidget.builder(this, 216, 10).size(182, 104).build(); this.colorPickerWidget.toggle(false); //start deactivated - this.addDrawableChild(colorPickerWidget); + this.addRenderableWidget(colorPickerWidget); - addDrawableChild(changeAlignment); - addDrawableChild(doneButton); - addDrawableChild(signButton); + addRenderableWidget(changeAlignment); + addRenderableWidget(doneButton); + addRenderableWidget(signButton); addFormattingButtons(width / 2 - BG_WIDTH / 2 + BG_WIDTH / 12 * 6 - 5 - 7, height / 2 - BG_HEIGHT / 2 - offset - 20 - 4, width / 100, 20, 2); } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (client == null) return; + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { + if (minecraft == null) return; super.render(context, mouseX, mouseY, delta); - List screen = signing ? signing_text : lines; + List screen = signing ? signing_text : lines; NoteComponent.Alignment alignment = signing ? NoteComponent.Alignment.LEFT : textAlignment; // Ensure no overflow is happening @@ -216,20 +219,20 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { // Text rendering boolean overflow = false; for (int i = 0; i < screen.size(); i++) { - StringVisitable text = screen.get(i); + FormattedText text = screen.get(i); if (signing && i >= 6 && i <= 7) - text = StringVisitable.concat(text, Text.of((i == 6) ? title : author)); + text = FormattedText.composite(text, Component.nullToEmpty((i == 6) ? title : author)); - if (outOfBounds(textRenderer, text)) - text = ensureBounds(textRenderer, text); + if (outOfBounds(font, text)) + text = ensureBounds(font, text); - int line_width = textRenderer.getWidth(text); + int line_width = font.width(text); float x = 0; if (i == currentRow && !signing) { - text = Text.literal(getRawLine(currentRow)); - line_width = textRenderer.getWidth(text); - if (outOfBounds(textRenderer, text)) { + text = Component.literal(getRawLine(currentRow)); + line_width = font.width(text); + if (outOfBounds(font, text)) { x += width / 2f + BG_WIDTH / 2f - TXT_X_PADDING / 2f - line_width + editing_line_offset; overflow = true; } @@ -243,30 +246,30 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { }; } - context.drawText(textRenderer, Language.getInstance().reorder(text), (int) x, (height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y) + (textRenderer.fontHeight * i), NoteTextColorResource.TXT_COLOR, false); + context.drawString(font, Language.getInstance().getVisualOrder(text), (int) x, (height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y) + (font.lineHeight * i), NoteTextColorResource.TXT_COLOR, false); if (overflow && i == currentRow) { //RenderSystem.enableBlend(); - for (int j = 0; j < textRenderer.fontHeight; j++) { - context.drawTexture(RenderPipelines.GUI_TEXTURED, TEXTURE, + for (int j = 0; j < font.lineHeight; j++) { + context.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, width / 2 - BG_WIDTH / 2 + SCREEN_X1, - height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (textRenderer.fontHeight * currentRow) + j, + height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (font.lineHeight * currentRow) + j, 0, BG_SIZE - 1, 32, 1, BG_SIZE, BG_SIZE ); - context.drawTexture(RenderPipelines.GUI_TEXTURED, TEXTURE, + context.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, width / 2 + BG_WIDTH / 2 + SCREEN_X2 - 32, - height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (textRenderer.fontHeight * currentRow) + j, + height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (font.lineHeight * currentRow) + j, 0, BG_SIZE - 2, 32, 1, BG_SIZE, BG_SIZE ); } if (x < (width / 2f - BG_WIDTH / 2f + SCREEN_X1)) { - context.drawText(textRenderer, ARROW_LEFT_SYMBOL, width / 2 - BG_WIDTH / 2 + SCREEN_X1 + 1, height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (textRenderer.fontHeight * currentRow), NoteTextColorResource.TXT_COLOR, false); + context.drawString(font, ARROW_LEFT_SYMBOL, width / 2 - BG_WIDTH / 2 + SCREEN_X1 + 1, height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (font.lineHeight * currentRow), NoteTextColorResource.TXT_COLOR, false); } if (editing_line_offset > 0) { - context.drawText(textRenderer, ARROW_RIGHT_SYMBOL, width / 2 + BG_WIDTH / 2 + SCREEN_X2 - textRenderer.getWidth(ARROW_RIGHT_SYMBOL) - 1, height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (textRenderer.fontHeight * currentRow), NoteTextColorResource.TXT_COLOR, false); + context.drawString(font, ARROW_RIGHT_SYMBOL, width / 2 + BG_WIDTH / 2 + SCREEN_X2 - font.width(ARROW_RIGHT_SYMBOL) - 1, height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y + (font.lineHeight * currentRow), NoteTextColorResource.TXT_COLOR, false); } //RenderSystem.disableBlend(); @@ -275,30 +278,30 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { // Cursor / Selection // I literally copied this from TextBlockEditScreen, we might want to abstract this further more down too - int caretStart = selectionManager.getSelectionStart(); - int caretEnd = selectionManager.getSelectionEnd(); + int caretStart = selectionManager.getCursorPos(); + int caretEnd = selectionManager.getSelectionPos(); if (caretStart >= 0) { String line = signing ? (currentRow == 6 ? title : author) : getRawLine(currentRow); - int selectionStart = MathHelper.clamp(Math.min(caretStart, caretEnd), 0, line.length()); - int selectionEnd = MathHelper.clamp(Math.max(caretStart, caretEnd), 0, line.length()); + int selectionStart = Mth.clamp(Math.min(caretStart, caretEnd), 0, line.length()); + int selectionEnd = Mth.clamp(Math.max(caretStart, caretEnd), 0, line.length()); - String preSelection = line.substring(0, MathHelper.clamp(line.length(), 0, selectionStart)); - int startX = client.textRenderer.getWidth(preSelection); - int caretStartY = (height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y) + (textRenderer.fontHeight * currentRow); + String preSelection = line.substring(0, Mth.clamp(line.length(), 0, selectionStart)); + int startX = minecraft.font.width(preSelection); + int caretStartY = (height / 2 - BG_HEIGHT / 2 + TXT_OFF_Y) + (font.lineHeight * currentRow); float push = switch (overflow ? NoteComponent.Alignment.RIGHT : alignment) { case LEFT -> width / 2f - BG_WIDTH / 2f + TXT_X_PADDING / 2f; - case CENTER -> width / 2f - textRenderer.getWidth(line) / 2f; - case RIGHT -> width / 2f + BG_WIDTH / 2f - TXT_X_PADDING / 2f - textRenderer.getWidth(line); + case CENTER -> width / 2f - font.width(line) / 2f; + case RIGHT -> width / 2f + BG_WIDTH / 2f - TXT_X_PADDING / 2f - font.width(line); }; startX += (int) push; if (signing) - startX += textRenderer.getWidth(screen.get(currentRow)); + startX += font.width(screen.get(currentRow)); if (overflow) { int apply = 0; @@ -317,13 +320,13 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (selectionStart < line.length()) { context.fill(startX, caretStartY, startX + 1, caretStartY + caretLength, 0xCC000000); } else { - context.drawText(textRenderer, "_", startX, caretStartY, NoteTextColorResource.TXT_COLOR, false); + context.drawString(font, "_", startX, caretStartY, NoteTextColorResource.TXT_COLOR, false); } } if (caretStart != caretEnd) { - int endX = startX + textRenderer.getWidth(line.substring(selectionStart, selectionEnd)); - context.drawSelection(startX, caretStartY, endX, caretStartY + 9); + int endX = startX + font.width(line.substring(selectionStart, selectionEnd)); + context.textHighlight(startX, caretStartY, endX, caretStartY + 9, false); } } @@ -336,15 +339,16 @@ public void tick() { } @Override - public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { - this.renderInGameBackground(context); - context.drawTexture(RenderPipelines.GUI_TEXTURED, TEXTURE, width / 2 - BG_WIDTH / 2, height / 2 - BG_HEIGHT / 2, 0, 0, BG_WIDTH, BG_HEIGHT, BG_SIZE, BG_SIZE); + public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) { + this.renderTransparentBackground(context); + context.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, width / 2 - BG_WIDTH / 2, height / 2 - BG_HEIGHT / 2, 0, 0, BG_WIDTH, BG_HEIGHT, BG_SIZE, BG_SIZE); } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + public boolean keyPressed(KeyEvent event) { boolean result; + int keyCode = event.key(); if (this.colorPickerWidget.active && (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_ESCAPE)) { if (keyCode == GLFW.GLFW_KEY_ENTER) { this.colorPickerWidget.confirmColor(); @@ -355,71 +359,71 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { } else { setFocused(null); result = true; - if (keyCode == GLFW.GLFW_KEY_UP || (keyCode == GLFW.GLFW_KEY_LEFT && selectionManager.getSelectionStart() <= 0 && currentRow > 0)) { + if (keyCode == GLFW.GLFW_KEY_UP || (keyCode == GLFW.GLFW_KEY_LEFT && selectionManager.getCursorPos() <= 0 && currentRow > 0)) { // Move cursor up currentRow = Math.max(currentRow - 1, signing ? 6 : 0); editing_line_offset = 0; - selectionManager.putCursorAtEnd(); - } else if (keyCode == GLFW.GLFW_KEY_DOWN || (keyCode == GLFW.GLFW_KEY_RIGHT && selectionManager.getSelectionStart() >= getRawLine(currentRow).length() && currentRow < NoteComponent.LINES_LIMIT - 1)) { + selectionManager.setCursorToEnd(); + } else if (keyCode == GLFW.GLFW_KEY_DOWN || (keyCode == GLFW.GLFW_KEY_RIGHT && selectionManager.getCursorPos() >= getRawLine(currentRow).length() && currentRow < NoteComponent.LINES_LIMIT - 1)) { // Move cursor down currentRow = Math.min(currentRow + 1, signing ? 7 : NoteComponent.LINES_LIMIT - 1); editing_line_offset = 0; if (keyCode == GLFW.GLFW_KEY_DOWN) - selectionManager.putCursorAtEnd(); + selectionManager.setCursorToEnd(); else - selectionManager.moveCursorToStart(); + selectionManager.setCursorToStart(); } else if (!signing && (currentRow < NoteComponent.LINES_LIMIT - 1) && (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)) { // Split lines (enter) if (hasSpaceLeft()) { - int cursor = selectionManager.getSelectionStart(); + int cursor = selectionManager.getCursorPos(); if (cursor <= 0) { - lines.add(currentRow, Text.of("")); + lines.add(currentRow, Component.nullToEmpty("")); currentRow++; - selectionManager.moveCursorToStart(); + selectionManager.setCursorToStart(); } else if (cursor >= getRawLine(currentRow).length()) { - lines.add(currentRow + 1, Text.of("")); + lines.add(currentRow + 1, Component.nullToEmpty("")); currentRow++; - selectionManager.moveCursorToStart(); + selectionManager.setCursorToStart(); } else { String curLine = getRawLine(currentRow); String newLine = curLine.substring(cursor); curLine = curLine.substring(0, cursor); setRawLine(currentRow, curLine); - lines.add(currentRow + 1, Text.of("")); + lines.add(currentRow + 1, Component.nullToEmpty("")); setRawLine(currentRow + 1, newLine); currentRow++; - selectionManager.moveCursorToStart(); + selectionManager.setCursorToStart(); } } - } else if (!signing && (currentRow > 0 && selectionManager.getSelectionStart() <= 0) && (keyCode == GLFW.GLFW_KEY_BACKSPACE)) { + } else if (!signing && (currentRow > 0 && selectionManager.getCursorPos() <= 0) && (keyCode == GLFW.GLFW_KEY_BACKSPACE)) { // Delete before cursor (backspace) String curLine = getRawLine(currentRow); String before = getRawLine(currentRow - 1); setRawLine(currentRow - 1, before + curLine); lines.remove(currentRow); - lines.add(Text.of("")); + lines.add(Component.nullToEmpty("")); currentRow--; - selectionManager.moveCursorToStart(); - selectionManager.moveCursor(before.length()); - } else if (!signing && (currentRow < NoteComponent.LINES_LIMIT - 1 && selectionManager.getSelectionStart() >= getRawLine(currentRow).length()) && (keyCode == GLFW.GLFW_KEY_DELETE)) { + selectionManager.setCursorToStart(); + selectionManager.moveByChars(before.length()); + } else if (!signing && (currentRow < NoteComponent.LINES_LIMIT - 1 && selectionManager.getCursorPos() >= getRawLine(currentRow).length()) && (keyCode == GLFW.GLFW_KEY_DELETE)) { // Delete after cursor (delete key) String curLine = getRawLine(currentRow); String after = getRawLine(currentRow + 1); setRawLine(currentRow, curLine + after); lines.remove(currentRow + 1); - lines.add(Text.of("")); + lines.add(Component.nullToEmpty("")); } else if (signing && keyCode == GLFW.GLFW_KEY_TAB) { // Tab currentRow = (currentRow == 6 ? 7 : 6); } else { // Rest - result = selectionManager.handleSpecialKey(keyCode) || super.keyPressed(keyCode, scanCode, modifiers); + result = selectionManager.keyPressed(event) || super.keyPressed(event); } } @@ -430,19 +434,21 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { } @Override - public boolean charTyped(char chr, int modifiers) { + public boolean charTyped(CharacterEvent event) { if (!signing || (currentRow == 6 ? title : author).length() < NoteComponent.TITLE_LIMIT) { - this.selectionManager.insert(chr); + this.selectionManager.charTyped(event); return true; } return false; } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double mouseX = event.x(); + double mouseY = event.y(); if (colorPickerWidget.active && colorPickerWidget.visible) { if (colorPickerWidget.isMouseOver(mouseX, mouseY)) { - colorPickerWidget.mouseClicked(mouseX, mouseY, button); + colorPickerWidget.mouseClicked(event, doubleClick); this.setFocused(colorPickerWidget); this.setDragging(true); return true; @@ -460,7 +466,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { this.setFocused(null); double linePos = mouseY - (height / 2f - BG_HEIGHT / 2f + TXT_OFF_Y); - double totalHeight = NoteComponent.LINES_LIMIT * textRenderer.fontHeight; + double totalHeight = NoteComponent.LINES_LIMIT * font.lineHeight; int clickedLine = Math.clamp( (int) (NoteComponent.LINES_LIMIT / totalHeight * linePos), @@ -474,20 +480,20 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { // Click on current line, get more precise in-row positioning String line = getRawLine(currentRow); int chars = line.length(); - Text text = Text.of(line); - int length = textRenderer.getWidth(text); + Component text = Component.nullToEmpty(line); + int length = font.width(text); int charPos = (int) mouseX; - if (outOfBounds(textRenderer, text)) { + if (outOfBounds(font, text)) { // Scrolling line charPos -= (int) (width / 2f + BG_WIDTH / 2f - TXT_X_PADDING / 2f - length + editing_line_offset); } else { // Non-scrolling line float offset = switch (textAlignment) { case LEFT -> width / 2f - BG_WIDTH / 2f + TXT_X_PADDING / 2f; - case CENTER -> width / 2f - textRenderer.getWidth(line) / 2f; - case RIGHT -> width / 2f + BG_WIDTH / 2f - TXT_X_PADDING / 2f - textRenderer.getWidth(line); + case CENTER -> width / 2f - font.width(line) / 2f; + case RIGHT -> width / 2f + BG_WIDTH / 2f - TXT_X_PADDING / 2f - font.width(line); }; charPos -= (int) offset; } @@ -495,17 +501,17 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { // Find spot to move the cursor to if (charPos >= length) { - selectionManager.putCursorAtEnd(); + selectionManager.setCursorToEnd(); } else if (charPos <= 0) { - selectionManager.moveCursorToStart(); + selectionManager.setCursorToStart(); } else { // Clicking mid-text for (int i = 1; i < chars; i++) { String testContents = line.substring(0, i); - int sub_width = textRenderer.getWidth(testContents); + int sub_width = font.width(testContents); if (charPos <= sub_width) { - selectionManager.moveCursorToStart(); - selectionManager.moveCursor(i); + selectionManager.setCursorToStart(); + selectionManager.moveByChars(i); break; } } @@ -513,18 +519,18 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } else { // Apply new line selection currentRow = clickedLine; - selectionManager.putCursorAtEnd(); + selectionManager.setCursorToEnd(); editing_line_offset = 0; } return true; } else { - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(event, doubleClick); } } private boolean hasSpaceLeft() { - Text last = lines.getLast(); + Component last = lines.getLast(); if (last.getString().isEmpty()) { lines.removeLast(); return true; @@ -538,29 +544,29 @@ public String getRawLine(int i) { } public void setRawLine(int i, String string) { - var parsed = PARSER.parseText(string, ParserContext.of()); + var parsed = PARSER.parseComponent(string, ParserContext.of()); if (parsed.getString().equals(string)) { - this.lines.set(i, Text.literal(string)); + this.lines.set(i, Component.literal(string)); } else { - this.lines.set(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); + this.lines.set(i, Component.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); } } - public static boolean outOfBounds(TextRenderer textRenderer, T text) { - int line_width = textRenderer.getWidth(text); + public static boolean outOfBounds(Font textRenderer, T text) { + int line_width = textRenderer.width(text); return (line_width > (BG_WIDTH - TXT_X_PADDING)); } - public static StringVisitable ensureBounds(TextRenderer textRenderer, StringVisitable text) { - StringVisitable ellipsis = StringVisitable.plain("..."); - return StringVisitable.concat( - textRenderer.trimToWidth(text, BG_WIDTH - TXT_X_PADDING - textRenderer.getWidth(ellipsis)), + public static FormattedText ensureBounds(Font textRenderer, FormattedText text) { + FormattedText ellipsis = FormattedText.of("..."); + return FormattedText.composite( + textRenderer.substrByWidth(text, BG_WIDTH - TXT_X_PADDING - textRenderer.width(ellipsis)), ellipsis ); } - public static String extractRaw(Text text) { + public static String extractRaw(Component text) { if (text.getStyle() == null) { return text.getString(); } @@ -574,14 +580,14 @@ public static String extractRaw(Text text) { } @Override - public void close() { - super.close(); + public void onClose() { + super.onClose(); if (finalizing) { // Remove insertion for optimization as it is not needed anymore for (int i = 0; i < lines.size(); i++) { String rawLine = getRawLine(i); - Text text = PARSER.parseText(rawLine, ParserContext.of()); + Component text = PARSER.parseComponent(rawLine, ParserContext.of()); lines.set(i, text); } } @@ -605,7 +611,7 @@ public void toggleColorPicker(boolean active) { } @Override - SelectionManager getSelectionManager() { + TextFieldHelper getSelectionManager() { return selectionManager; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/OutlineBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/OutlineBlockEditScreen.java index 2bf6a0f7..1d3fde23 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/OutlineBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/OutlineBlockEditScreen.java @@ -4,28 +4,27 @@ import dev.hephaestus.glowcase.block.entity.OutlineBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditOutlineBlock; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.gui.widget.TextWidget; -import net.minecraft.text.Text; -import net.minecraft.text.TextColor; -import net.minecraft.util.math.Vec3i; - import java.util.function.Predicate; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.core.Vec3i; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextColor; public class OutlineBlockEditScreen extends GlowcaseScreen { private static final Predicate TEXT_PREDICATE = s -> s.matches("-?\\d*"); private final OutlineBlockEntity outlineBlockEntity; - private TextWidget offsetWidget; - private TextWidget scaleWidget; - private TextFieldWidget xOffsetWidget; - private TextFieldWidget yOffsetWidget; - private TextFieldWidget zOffsetWidget; - private TextFieldWidget xScaleWidget; - private TextFieldWidget yScaleWidget; - private TextFieldWidget zScaleWidget; - private TextFieldWidget colorEntryWidget; + private StringWidget offsetWidget; + private StringWidget scaleWidget; + private EditBox xOffsetWidget; + private EditBox yOffsetWidget; + private EditBox zOffsetWidget; + private EditBox xScaleWidget; + private EditBox yScaleWidget; + private EditBox zScaleWidget; + private EditBox colorEntryWidget; public OutlineBlockEditScreen(OutlineBlockEntity outlineBlockEntity) { this.outlineBlockEntity = outlineBlockEntity; @@ -35,100 +34,101 @@ public OutlineBlockEditScreen(OutlineBlockEntity outlineBlockEntity) { public void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; - this.offsetWidget = new TextWidget(width / 2 - 110, height / 2 - 25, 40, 20, Text.translatable("gui.glowcase.offset"), this.textRenderer); - this.scaleWidget = new TextWidget(width / 2 - 110, height / 2 + 5, 40, 20, Text.translatable("gui.glowcase.scale"), this.textRenderer); + this.offsetWidget = new StringWidget(width / 2 - 110, height / 2 - 25, 40, 20, Component.translatable("gui.glowcase.offset"), this.font); + this.scaleWidget = new StringWidget(width / 2 - 110, height / 2 + 5, 40, 20, Component.translatable("gui.glowcase.scale"), this.font); - this.xOffsetWidget = new TextFieldWidget(this.textRenderer, width / 2 - 65, height / 2 - 25, 40, 20, Text.empty()); - this.yOffsetWidget = new TextFieldWidget(this.textRenderer, width / 2 - 20, height / 2 - 25, 40, 20, Text.empty()); - this.zOffsetWidget = new TextFieldWidget(this.textRenderer, width / 2 + 25, height / 2 - 25, 40, 20, Text.empty()); + this.xOffsetWidget = new EditBox(this.font, width / 2 - 65, height / 2 - 25, 40, 20, Component.empty()); + this.yOffsetWidget = new EditBox(this.font, width / 2 - 20, height / 2 - 25, 40, 20, Component.empty()); + this.zOffsetWidget = new EditBox(this.font, width / 2 + 25, height / 2 - 25, 40, 20, Component.empty()); - this.xScaleWidget = new TextFieldWidget(this.textRenderer, width / 2 - 65, height / 2 + 5, 40, 20, Text.empty()); - this.yScaleWidget = new TextFieldWidget(this.textRenderer, width / 2 - 20, height / 2 + 5, 40, 20, Text.empty()); - this.zScaleWidget = new TextFieldWidget(this.textRenderer, width / 2 + 25, height / 2 + 5, 40, 20, Text.empty()); + this.xScaleWidget = new EditBox(this.font, width / 2 - 65, height / 2 + 5, 40, 20, Component.empty()); + this.yScaleWidget = new EditBox(this.font, width / 2 - 20, height / 2 + 5, 40, 20, Component.empty()); + this.zScaleWidget = new EditBox(this.font, width / 2 + 25, height / 2 + 5, 40, 20, Component.empty()); - this.xOffsetWidget.setText(String.valueOf(this.outlineBlockEntity.offset.getX())); - this.yOffsetWidget.setText(String.valueOf(this.outlineBlockEntity.offset.getY())); - this.zOffsetWidget.setText(String.valueOf(this.outlineBlockEntity.offset.getZ())); - this.xScaleWidget.setText(String.valueOf(this.outlineBlockEntity.scale.getX())); - this.yScaleWidget.setText(String.valueOf(this.outlineBlockEntity.scale.getY())); - this.zScaleWidget.setText(String.valueOf(this.outlineBlockEntity.scale.getZ())); + this.xOffsetWidget.setValue(String.valueOf(this.outlineBlockEntity.offset.getX())); + this.yOffsetWidget.setValue(String.valueOf(this.outlineBlockEntity.offset.getY())); + this.zOffsetWidget.setValue(String.valueOf(this.outlineBlockEntity.offset.getZ())); + this.xScaleWidget.setValue(String.valueOf(this.outlineBlockEntity.scale.getX())); + this.yScaleWidget.setValue(String.valueOf(this.outlineBlockEntity.scale.getY())); + this.zScaleWidget.setValue(String.valueOf(this.outlineBlockEntity.scale.getZ())); - this.xOffsetWidget.setTextPredicate(TEXT_PREDICATE); - this.yOffsetWidget.setTextPredicate(TEXT_PREDICATE); - this.zOffsetWidget.setTextPredicate(TEXT_PREDICATE); - this.xScaleWidget.setTextPredicate(TEXT_PREDICATE); - this.yScaleWidget.setTextPredicate(TEXT_PREDICATE); - this.zScaleWidget.setTextPredicate(TEXT_PREDICATE); +// FIXME 26.1 +// this.xOffsetWidget.setFilter(TEXT_PREDICATE); +// this.yOffsetWidget.setFilter(TEXT_PREDICATE); +// this.zOffsetWidget.setFilter(TEXT_PREDICATE); +// this.xScaleWidget.setFilter(TEXT_PREDICATE); +// this.yScaleWidget.setFilter(TEXT_PREDICATE); +// this.zScaleWidget.setFilter(TEXT_PREDICATE); - this.xOffsetWidget.setChangedListener(string -> { + this.xOffsetWidget.setResponder(string -> { if (Ints.tryParse(string) instanceof Integer x) { Vec3i offset = this.outlineBlockEntity.offset; this.outlineBlockEntity.offset = new Vec3i(x, offset.getY(), offset.getZ()); } }); - this.yOffsetWidget.setChangedListener(string -> { + this.yOffsetWidget.setResponder(string -> { if (Ints.tryParse(string) instanceof Integer y) { Vec3i offset = this.outlineBlockEntity.offset; this.outlineBlockEntity.offset = new Vec3i(offset.getX(), y, offset.getZ()); } }); - this.zOffsetWidget.setChangedListener(string -> { + this.zOffsetWidget.setResponder(string -> { if (Ints.tryParse(string) instanceof Integer z) { Vec3i offset = this.outlineBlockEntity.offset; this.outlineBlockEntity.offset = new Vec3i(offset.getX(), offset.getY(), z); } }); - this.xScaleWidget.setChangedListener(string -> { + this.xScaleWidget.setResponder(string -> { if (Ints.tryParse(string) instanceof Integer x) { Vec3i scale = this.outlineBlockEntity.scale; this.outlineBlockEntity.scale = new Vec3i(x, scale.getY(), scale.getZ()); } }); - this.yScaleWidget.setChangedListener(string -> { + this.yScaleWidget.setResponder(string -> { if (Ints.tryParse(string) instanceof Integer y) { Vec3i scale = this.outlineBlockEntity.scale; this.outlineBlockEntity.scale = new Vec3i(scale.getX(), y, scale.getZ()); } }); - this.zScaleWidget.setChangedListener(string -> { + this.zScaleWidget.setResponder(string -> { if (Ints.tryParse(string) instanceof Integer z) { Vec3i scale = this.outlineBlockEntity.scale; this.outlineBlockEntity.scale = new Vec3i(scale.getX(), scale.getY(), z); } }); - this.xOffsetWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.x")); - this.yOffsetWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.y")); - this.zOffsetWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.z")); - this.xScaleWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.x")); - this.yScaleWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.y")); - this.zScaleWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.z")); - - this.colorEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 2 - 25, height / 2 + 35, 50, 20, Text.empty()); - this.colorEntryWidget.setText("#" + String.format("%1$06X", this.outlineBlockEntity.color & 0x00FFFFFF)); - this.colorEntryWidget.setChangedListener(string -> { - TextColor.parse(this.colorEntryWidget.getText()).ifSuccess(color -> { - this.outlineBlockEntity.color = color == null ? 0xFFFFFFFF : color.getRgb() | 0xFF000000; + this.xOffsetWidget.setHint(TextUtils.placeholder("gui.glowcase.x")); + this.yOffsetWidget.setHint(TextUtils.placeholder("gui.glowcase.y")); + this.zOffsetWidget.setHint(TextUtils.placeholder("gui.glowcase.z")); + this.xScaleWidget.setHint(TextUtils.placeholder("gui.glowcase.x")); + this.yScaleWidget.setHint(TextUtils.placeholder("gui.glowcase.y")); + this.zScaleWidget.setHint(TextUtils.placeholder("gui.glowcase.z")); + + this.colorEntryWidget = new EditBox(this.minecraft.font, width / 2 - 25, height / 2 + 35, 50, 20, Component.empty()); + this.colorEntryWidget.setValue("#" + String.format("%1$06X", this.outlineBlockEntity.color & 0x00FFFFFF)); + this.colorEntryWidget.setResponder(string -> { + TextColor.parseColor(this.colorEntryWidget.getValue()).ifSuccess(color -> { + this.outlineBlockEntity.color = color == null ? 0xFFFFFFFF : color.getValue() | 0xFF000000; }); }); - this.addDrawableChild(this.offsetWidget); - this.addDrawableChild(this.scaleWidget); - this.addDrawableChild(this.xOffsetWidget); - this.addDrawableChild(this.yOffsetWidget); - this.addDrawableChild(this.zOffsetWidget); - this.addDrawableChild(this.xScaleWidget); - this.addDrawableChild(this.yScaleWidget); - this.addDrawableChild(this.zScaleWidget); - this.addDrawableChild(this.colorEntryWidget); + this.addRenderableWidget(this.offsetWidget); + this.addRenderableWidget(this.scaleWidget); + this.addRenderableWidget(this.xOffsetWidget); + this.addRenderableWidget(this.yOffsetWidget); + this.addRenderableWidget(this.zOffsetWidget); + this.addRenderableWidget(this.xScaleWidget); + this.addRenderableWidget(this.yScaleWidget); + this.addRenderableWidget(this.zScaleWidget); + this.addRenderableWidget(this.colorEntryWidget); } @Override - public void close() { + public void onClose() { C2SEditOutlineBlock.of(outlineBlockEntity).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ParticleDisplayEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ParticleDisplayEditScreen.java index 8558dd76..a84a7a58 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ParticleDisplayEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ParticleDisplayEditScreen.java @@ -12,22 +12,23 @@ import dev.hephaestus.glowcase.util.DeviatedVec3d; import dev.hephaestus.glowcase.util.ParseUtil; import dev.hephaestus.glowcase.packet.C2SEditParticleDisplayBlock; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; -import net.minecraft.nbt.StringNbtReader; -import net.minecraft.particle.ParticleEffect; -import net.minecraft.particle.ParticleType; -import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - +import net.minecraft.nbt.Tag; +import net.minecraft.nbt.TagParser; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.Identifier; import java.util.Objects; import java.util.Optional; import java.util.ArrayList; @@ -36,7 +37,7 @@ public class ParticleDisplayEditScreen extends GlowcaseScreen { private final ParticleDisplayBlockEntity blockEntity; - private TextFieldWidget particleId; + private EditBox particleId; private Vec3FieldsWidget positionMean; private Vec3FieldsWidget positionStdDev; @@ -44,11 +45,11 @@ public class ParticleDisplayEditScreen extends GlowcaseScreen { private Vec3FieldsWidget velocityMean; private Vec3FieldsWidget velocityStdDev; - private TextFieldWidget countMean; - private TextFieldWidget countStdDev; + private EditBox countMean; + private EditBox countStdDev; - private TextFieldWidget tickRateMean; - private TextFieldWidget tickRateStdDev; + private EditBox tickRateMean; + private EditBox tickRateStdDev; private SuggestionListWidget suggestionWidget; private List validParticles = new ArrayList<>(); @@ -60,34 +61,34 @@ public ParticleDisplayEditScreen(ParticleDisplayBlockEntity blockEntity) { @Override protected void init() { super.init(); - Objects.requireNonNull(this.client); - RegistryWrapper.WrapperLookup lookup = Objects.requireNonNull(client.world).getRegistryManager(); + Objects.requireNonNull(this.minecraft); + HolderLookup.Provider lookup = Objects.requireNonNull(minecraft.level).registryAccess(); // region Particle ID particleId = new GlowcaseTextFieldWidget( - this.client.textRenderer, + this.minecraft.font, width / 10, height / 2 - 110, 8 * width / 10, 20, - Text.empty() + Component.empty() ); particleId.setMaxLength(9999); - String optionsString = effectToTag(blockEntity.particle, lookup.getOps(NbtOps.INSTANCE)).toString(); + String optionsString = effectToTag(blockEntity.particle, lookup.createSerializationContext(NbtOps.INSTANCE)).toString(); if (optionsString.equals("{}")) optionsString = ""; - particleId.setText(Registries.PARTICLE_TYPE.getId(blockEntity.particle.getType()) + optionsString); + particleId.setValue(BuiltInRegistries.PARTICLE_TYPE.getKey(blockEntity.particle.getType()) + optionsString); - this.addDrawableChild(particleId); + this.addRenderableWidget(particleId); - validParticles = Registries.PARTICLE_TYPE.stream() - .map(Registries.PARTICLE_TYPE::getId) + validParticles = BuiltInRegistries.PARTICLE_TYPE.stream() + .map(BuiltInRegistries.PARTICLE_TYPE::getKey) .collect(Collectors.toList()); - suggestionWidget = SuggestionListWidget.forTextFieldWithStaticSuggestions(particleId, client.textRenderer, validParticles, Identifier::toString, this); + suggestionWidget = SuggestionListWidget.forTextFieldWithStaticSuggestions(particleId, minecraft.font, validParticles, Identifier::toString, this); - particleId.setChangedListener((text) -> { + particleId.setResponder((text) -> { suggestionWidget.updateSuggestions(validParticles, text, this); }); // endregion @@ -96,153 +97,157 @@ protected void init() { positionMean = new Vec3FieldsWidget( width / 10, height / 2 - 60, (4 * width / 10) - 6, 20, - this.client, + this.minecraft, blockEntity.position.mean() ); - this.addDrawableChild(positionMean); + this.addRenderableWidget(positionMean); positionStdDev = new Vec3FieldsWidget( width / 10 + (4 * width / 10) + 6, height / 2 - 60, (4 * width / 10) - 6, 20, - this.client, + this.minecraft, blockEntity.position.stdDev() ); - this.addDrawableChild(positionStdDev); + this.addRenderableWidget(positionStdDev); // endregion // region Velocity velocityMean = new Vec3FieldsWidget( width / 10, (height / 2) - 10, (4 * width / 10) - 6, 20, - this.client, + this.minecraft, blockEntity.velocity.mean() ); - this.addDrawableChild(velocityMean); + this.addRenderableWidget(velocityMean); velocityStdDev = new Vec3FieldsWidget( width / 10 + (4 * width / 10) + 6, (height / 2) - 10, (4 * width / 10) - 6, 20, - this.client, + this.minecraft, blockEntity.velocity.stdDev() ); - this.addDrawableChild(velocityStdDev); + this.addRenderableWidget(velocityStdDev); // endregion // region Count - countMean = new TextFieldWidget( - this.client.textRenderer, + countMean = new EditBox( + this.minecraft.font, width / 10, height / 2 + 40, (4 * width / 10) - 6, 20, - Text.empty() + Component.empty() ); - countMean.setText(String.valueOf(blockEntity.count.mean())); - countMean.setTextPredicate(ParseUtil::canParseInt); + countMean.setValue(String.valueOf(blockEntity.count.mean())); + //FIXME 26.1 +// countMean.setFilter(ParseUtil::canParseInt); - this.addDrawableChild(countMean); + this.addRenderableWidget(countMean); - countStdDev = new TextFieldWidget( - this.client.textRenderer, + countStdDev = new EditBox( + this.minecraft.font, width / 10 + (4 * width / 10) + 6, height / 2 + 40, (4 * width / 10) - 6, 20, - Text.empty() + Component.empty() ); - countStdDev.setText(String.valueOf(blockEntity.count.stdDev())); - countStdDev.setTextPredicate(ParseUtil::canParseInt); + countStdDev.setValue(String.valueOf(blockEntity.count.stdDev())); + //FIXME 26.1 +// countStdDev.setFilter(ParseUtil::canParseInt); - this.addDrawableChild(countStdDev); + this.addRenderableWidget(countStdDev); // endregion // region Tick Rate - tickRateMean = new TextFieldWidget( - this.client.textRenderer, + tickRateMean = new EditBox( + this.minecraft.font, width / 10, height / 2 + 90, (4 * width / 10) - 6, 20, - Text.empty() + Component.empty() ); - tickRateMean.setText(String.valueOf(blockEntity.tickRate.mean())); - tickRateMean.setTextPredicate(ParseUtil::canParseInt); + tickRateMean.setValue(String.valueOf(blockEntity.tickRate.mean())); + //FIXME 26.1 +// tickRateMean.setFilter(ParseUtil::canParseInt); - this.addDrawableChild(tickRateMean); + this.addRenderableWidget(tickRateMean); - tickRateStdDev = new TextFieldWidget( - this.client.textRenderer, + tickRateStdDev = new EditBox( + this.minecraft.font, width / 10 + (4 * width / 10) + 6, height / 2 + 90, (4 * width / 10) - 6, 20, - Text.empty() + Component.empty() ); - tickRateStdDev.setText(String.valueOf(blockEntity.tickRate.stdDev())); - tickRateStdDev.setTextPredicate(ParseUtil::canParseInt); + tickRateStdDev.setValue(String.valueOf(blockEntity.tickRate.stdDev())); + //FIXME 26.1 +// tickRateStdDev.setFilter(ParseUtil::canParseInt); - this.addDrawableChild(tickRateStdDev); + this.addRenderableWidget(tickRateStdDev); // endregion } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); - Objects.requireNonNull(this.client); + Objects.requireNonNull(this.minecraft); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.position_mean"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.position_mean"), width / 10, (height / 2 - 60) - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.position_std_dev"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.position_std_dev"), width / 10 + (4 * width / 10) + 6, (height / 2 - 60) - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.velocity_mean"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.velocity_mean"), width / 10, (height / 2 - 10) - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.velocity_std_dev"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.velocity_std_dev"), width / 10 + (4 * width / 10) + 6, (height / 2 - 10) - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.count_mean"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.count_mean"), width / 10, (height / 2 + 40) - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.count_std_dev"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.count_std_dev"), width / 10 + (4 * width / 10) + 6, (height / 2 + 40) - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.tick_rate_mean"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.tick_rate_mean"), width / 10, (height / 2 + 90) - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - client.textRenderer, - Text.translatable("gui.glowcase.tick_rate_std_dev"), + context.drawString( + minecraft.font, + Component.translatable("gui.glowcase.tick_rate_std_dev"), width / 10 + (4 * width / 10) + 6, (height / 2 + 90) - 20, 0xFFFFFFFF ); @@ -262,60 +267,61 @@ public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmou } @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) { if (suggestionWidget.draggingScrollbar) { - if (suggestionWidget.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) + if (suggestionWidget.mouseDragged(event, dx, dy)) return true; } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + return super.mouseDragged(event, dx, dy); } - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double mouseX = event.x(); + double mouseY = event.y(); if (suggestionWidget.isMouseOver(mouseX, mouseY) && particleId.isFocused()) { - return suggestionWidget.mouseClicked(mouseX, mouseY, button); + return suggestionWidget.mouseClicked(event, doubleClick); } else { suggestionWidget.updateSuggestions(new ArrayList<>(), "", this); } - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(event, doubleClick); } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (suggestionWidget.keyPressed(keyCode, scanCode, modifiers)) { + public boolean keyPressed(KeyEvent event) { + if (suggestionWidget.keyPressed(event)) { return true; } - return super.keyPressed(keyCode, scanCode, modifiers); + return super.keyPressed(event); } @Override - public void close() { + public void onClose() { setParticle(); blockEntity.position = new DeviatedVec3d(positionMean.value(), positionStdDev.value()); blockEntity.velocity = new DeviatedVec3d(velocityMean.value(), velocityStdDev.value()); blockEntity.count = new DeviatedInteger( - ParseUtil.parseOrDefault(countMean.getText(), blockEntity.count.mean()), - ParseUtil.parseOrDefault(countStdDev.getText(), blockEntity.count.stdDev()) + ParseUtil.parseOrDefault(countMean.getValue(), blockEntity.count.mean()), + ParseUtil.parseOrDefault(countStdDev.getValue(), blockEntity.count.stdDev()) ); blockEntity.tickRate = new DeviatedInteger( - ParseUtil.parseOrDefault(tickRateMean.getText(), blockEntity.tickRate.mean()), - ParseUtil.parseOrDefault(tickRateStdDev.getText(), blockEntity.tickRate.stdDev()) + ParseUtil.parseOrDefault(tickRateMean.getValue(), blockEntity.tickRate.mean()), + ParseUtil.parseOrDefault(tickRateStdDev.getValue(), blockEntity.tickRate.stdDev()) ); C2SEditParticleDisplayBlock.of(blockEntity).send(); - super.close(); + super.onClose(); } @SuppressWarnings("unchecked") private void setParticle() { - Objects.requireNonNull(this.client); + Objects.requireNonNull(this.minecraft); - String idText = particleId.getText(); + String idText = particleId.getValue(); int paramStart = idText.indexOf('{'); @@ -323,24 +329,24 @@ private void setParticle() { paramStart == -1 ? idText : idText.substring(0, paramStart)); if (id == null) return; - RegistryWrapper.WrapperLookup lookup = Objects.requireNonNull(this.client.world).getRegistryManager(); + HolderLookup.Provider lookup = Objects.requireNonNull(this.minecraft.level).registryAccess(); - RegistryKey> key = RegistryKey.of(RegistryKeys.PARTICLE_TYPE, id); + ResourceKey> key = ResourceKey.create(Registries.PARTICLE_TYPE, id); - Optional>> optionalType = lookup.getOrThrow(RegistryKeys.PARTICLE_TYPE).getOptional(key); + Optional>> optionalType = lookup.lookupOrThrow(Registries.PARTICLE_TYPE).get(key); if (optionalType.isEmpty()) return; - ParticleType type = (ParticleType) optionalType.get().value(); + ParticleType type = (ParticleType) optionalType.get().value(); - NbtCompound nbtCompound; + CompoundTag nbtCompound; try { - nbtCompound = paramStart == -1 ? new NbtCompound() : StringNbtReader.readCompound(idText.substring(paramStart)); + nbtCompound = paramStart == -1 ? new CompoundTag() : TagParser.parseCompoundFully(idText.substring(paramStart)); } catch (CommandSyntaxException e) { return; } - DataResult effect = type.getCodec().codec().parse(lookup.getOps(NbtOps.INSTANCE), nbtCompound); + DataResult effect = type.codec().codec().parse(lookup.createSerializationContext(NbtOps.INSTANCE), nbtCompound); if (effect.result().isEmpty()) return; @@ -348,8 +354,8 @@ private void setParticle() { } @SuppressWarnings("unchecked") - private NbtElement effectToTag(T effect, DynamicOps ops) { - Codec codec = (Codec) effect.getType().getCodec().codec(); + private Tag effectToTag(T effect, DynamicOps ops) { + Codec codec = (Codec) effect.getType().codec().codec(); return codec.encodeStart(ops, effect).getOrThrow(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockEditScreen.java index daa96977..24771d0f 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockEditScreen.java @@ -5,26 +5,29 @@ import dev.hephaestus.glowcase.block.entity.TextBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditPopupBlock; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.util.SelectionManager; -import net.minecraft.text.Text; -import net.minecraft.text.TextColor; -import net.minecraft.util.math.MathHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.font.TextFieldHelper; +import net.minecraft.client.input.CharacterEvent; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextColor; +import net.minecraft.util.Mth; import org.lwjgl.glfw.GLFW; //TODO: multi-character selection at some point? it may be a bit complex but it'd be nice public class PopupBlockEditScreen extends GlowcaseScreen { private final PopupBlockEntity popupBlockEntity; - private SelectionManager selectionManager; + private TextFieldHelper selectionManager; private int currentRow; private long ticksSinceOpened = 0; - private TextFieldWidget titleEntryWidget; - private ButtonWidget changeAlignment; - private TextFieldWidget colorEntryWidget; + private EditBox titleEntryWidget; + private Button changeAlignment; + private EditBox colorEntryWidget; public PopupBlockEditScreen(PopupBlockEntity popupBlockEntity) { this.popupBlockEntity = popupBlockEntity; @@ -36,26 +39,26 @@ public void init() { int innerPadding = width / 100; - this.selectionManager = new SelectionManager( + this.selectionManager = new TextFieldHelper( () -> this.popupBlockEntity.getRawLine(this.currentRow), (string) -> { popupBlockEntity.setRawLine(this.currentRow, string); this.popupBlockEntity.renderDirty = true; }, - SelectionManager.makeClipboardGetter(this.client), - SelectionManager.makeClipboardSetter(this.client), + TextFieldHelper.createClipboardGetter(this.minecraft), + TextFieldHelper.createClipboardSetter(this.minecraft), (string) -> true); - this.titleEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 10, 0, 8 * width / 10, 20, Text.empty()); + this.titleEntryWidget = new EditBox(this.minecraft.font, width / 10, 0, 8 * width / 10, 20, Component.empty()); this.titleEntryWidget.setMaxLength(HyperlinkBlockEntity.TITLE_MAX_LENGTH); - this.titleEntryWidget.setText(this.popupBlockEntity.title); - this.titleEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.title")); - this.titleEntryWidget.setChangedListener(string -> { - this.popupBlockEntity.title = this.titleEntryWidget.getText(); + this.titleEntryWidget.setValue(this.popupBlockEntity.title); + this.titleEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.title")); + this.titleEntryWidget.setResponder(string -> { + this.popupBlockEntity.title = this.titleEntryWidget.getValue(); this.popupBlockEntity.renderDirty = true; }); - this.changeAlignment = ButtonWidget.builder(Text.stringifiedTranslatable("gui.glowcase.alignment", this.popupBlockEntity.textAlignment), action -> { + this.changeAlignment = Button.builder(Component.translatableEscape("gui.glowcase.alignment", this.popupBlockEntity.textAlignment), action -> { switch (popupBlockEntity.textAlignment) { case LEFT -> popupBlockEntity.textAlignment = TextBlockEntity.TextAlignment.CENTER; case CENTER, CENTER_LEFT, CENTER_RIGHT -> popupBlockEntity.textAlignment = TextBlockEntity.TextAlignment.RIGHT; @@ -63,21 +66,21 @@ public void init() { } this.popupBlockEntity.renderDirty = true; - this.changeAlignment.setMessage(Text.stringifiedTranslatable("gui.glowcase.alignment", this.popupBlockEntity.textAlignment)); - }).dimensions(120 + innerPadding, 20 + innerPadding, 160, 20).build(); + this.changeAlignment.setMessage(Component.translatableEscape("gui.glowcase.alignment", this.popupBlockEntity.textAlignment)); + }).bounds(120 + innerPadding, 20 + innerPadding, 160, 20).build(); - this.colorEntryWidget = new TextFieldWidget(this.client.textRenderer, 280 + innerPadding * 2, 20 + innerPadding, 50, 20, Text.empty()); - this.colorEntryWidget.setText("#" + Integer.toHexString(this.popupBlockEntity.color & 0x00FFFFFF)); - this.colorEntryWidget.setChangedListener(string -> { - TextColor.parse(this.colorEntryWidget.getText()).ifSuccess(color -> { - this.popupBlockEntity.color = color == null ? 0xFFFFFFFF : color.getRgb() | 0xFF000000; + this.colorEntryWidget = new EditBox(this.minecraft.font, 280 + innerPadding * 2, 20 + innerPadding, 50, 20, Component.empty()); + this.colorEntryWidget.setValue("#" + Integer.toHexString(this.popupBlockEntity.color & 0x00FFFFFF)); + this.colorEntryWidget.setResponder(string -> { + TextColor.parseColor(this.colorEntryWidget.getValue()).ifSuccess(color -> { + this.popupBlockEntity.color = color == null ? 0xFFFFFFFF : color.getValue() | 0xFF000000; this.popupBlockEntity.renderDirty = true; }); }); - this.addDrawableChild(this.titleEntryWidget); - this.addDrawableChild(this.changeAlignment); - this.addDrawableChild(this.colorEntryWidget); + this.addRenderableWidget(this.titleEntryWidget); + this.addRenderableWidget(this.changeAlignment); + this.addRenderableWidget(this.colorEntryWidget); } @Override @@ -86,130 +89,131 @@ public void tick() { } @Override - public void close() { + public void onClose() { C2SEditPopupBlock.of(popupBlockEntity).send(); - super.close(); + super.onClose(); } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (this.client == null) return; + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { + if (this.minecraft == null) return; super.render(context, mouseX, mouseY, delta); - context.getMatrices().pushMatrix(); - context.getMatrices().translate(0, 40 + 2 * this.width / 100F); + context.pose().pushMatrix(); + context.pose().translate(0, 40 + 2 * this.width / 100F); for (int i = 0; i < this.popupBlockEntity.lines.size(); ++i) { - var text = this.currentRow == i ? Text.literal(this.popupBlockEntity.getRawLine(i)) : this.popupBlockEntity.lines.get(i); + var text = this.currentRow == i ? Component.literal(this.popupBlockEntity.getRawLine(i)) : this.popupBlockEntity.lines.get(i); - int lineWidth = this.textRenderer.getWidth(text); + int lineWidth = this.font.width(text); switch (this.popupBlockEntity.textAlignment) { - case LEFT -> context.drawTextWithShadow(client.textRenderer, text, this.width / 10, i * 12, this.popupBlockEntity.color); - case CENTER, CENTER_LEFT, CENTER_RIGHT -> context.drawTextWithShadow(client.textRenderer, text, this.width / 2 - lineWidth / 2, i * 12, this.popupBlockEntity.color); - case RIGHT -> context.drawTextWithShadow(client.textRenderer, text, this.width - this.width / 10 - lineWidth, i * 12, this.popupBlockEntity.color); + case LEFT -> context.drawString(minecraft.font, text, this.width / 10, i * 12, this.popupBlockEntity.color); + case CENTER, CENTER_LEFT, CENTER_RIGHT -> context.drawString(minecraft.font, text, this.width / 2 - lineWidth / 2, i * 12, this.popupBlockEntity.color); + case RIGHT -> context.drawString(minecraft.font, text, this.width - this.width / 10 - lineWidth, i * 12, this.popupBlockEntity.color); } } - int caretStart = this.selectionManager.getSelectionStart(); - int caretEnd = this.selectionManager.getSelectionEnd(); + int caretStart = this.selectionManager.getCursorPos(); + int caretEnd = this.selectionManager.getSelectionPos(); if (caretStart >= 0) { String line = this.popupBlockEntity.getRawLine(this.currentRow); - int selectionStart = MathHelper.clamp(Math.min(caretStart, caretEnd), 0, line.length()); - int selectionEnd = MathHelper.clamp(Math.max(caretStart, caretEnd), 0, line.length()); + int selectionStart = Mth.clamp(Math.min(caretStart, caretEnd), 0, line.length()); + int selectionEnd = Mth.clamp(Math.max(caretStart, caretEnd), 0, line.length()); - String preSelection = line.substring(0, MathHelper.clamp(line.length(), 0, selectionStart)); - int startX = this.client.textRenderer.getWidth(preSelection); + String preSelection = line.substring(0, Mth.clamp(line.length(), 0, selectionStart)); + int startX = this.minecraft.font.width(preSelection); float push = switch (this.popupBlockEntity.textAlignment) { case LEFT -> this.width / 10F; - case CENTER, CENTER_LEFT, CENTER_RIGHT -> this.width / 2F - this.textRenderer.getWidth(line) / 2F; - case RIGHT -> this.width - this.width / 10F - this.textRenderer.getWidth(line); + case CENTER, CENTER_LEFT, CENTER_RIGHT -> this.width / 2F - this.font.width(line) / 2F; + case RIGHT -> this.width - this.width / 10F - this.font.width(line); }; startX += (int) push; int caretStartY = this.currentRow * 12; - if (this.ticksSinceOpened / 6 % 2 == 0 && !this.titleEntryWidget.isActive() && !this.colorEntryWidget.isActive()) { + if (this.ticksSinceOpened / 6 % 2 == 0 && !this.titleEntryWidget.canConsumeInput() && !this.colorEntryWidget.canConsumeInput()) { if (selectionStart < line.length()) { context.fill(startX, caretStartY, startX + 1, caretStartY + 9, 0xCCFFFFFF); } else { - context.drawText(client.textRenderer, "_", startX, this.currentRow * 12, 0xFFFFFFFF, false); + context.drawString(minecraft.font, "_", startX, this.currentRow * 12, 0xFFFFFFFF, false); } } if (caretStart != caretEnd) { - int endX = startX + this.client.textRenderer.getWidth(line.substring(selectionStart, selectionEnd)); - context.drawSelection(startX, caretStartY, endX, caretStartY + 9); + int endX = startX + this.minecraft.font.width(line.substring(selectionStart, selectionEnd)); + context.textHighlight(startX, caretStartY, endX, caretStartY + 9, false); } } - context.getMatrices().popMatrix(); + context.pose().popMatrix(); } @Override - public boolean charTyped(char chr, int keyCode) { - if (this.titleEntryWidget.isActive()) { - return this.titleEntryWidget.charTyped(chr, keyCode); - } else if (this.colorEntryWidget.isActive()) { - return this.colorEntryWidget.charTyped(chr, keyCode); + public boolean charTyped(CharacterEvent event) { + if (this.titleEntryWidget.canConsumeInput()) { + return this.titleEntryWidget.charTyped(event); + } else if (this.colorEntryWidget.canConsumeInput()) { + return this.colorEntryWidget.charTyped(event); } else { - this.selectionManager.insert(chr); + this.selectionManager.charTyped(event); return true; } } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (this.titleEntryWidget.isActive()) { + public boolean keyPressed(KeyEvent event) { + int keyCode = event.key(); + if (this.titleEntryWidget.canConsumeInput()) { if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - this.close(); + this.onClose(); return true; } else { - return this.titleEntryWidget.keyPressed(keyCode, scanCode, modifiers); + return this.titleEntryWidget.keyPressed(event); } - } else if (this.colorEntryWidget.isActive()) { + } else if (this.colorEntryWidget.canConsumeInput()) { if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - this.close(); + this.onClose(); return true; } else { - return this.colorEntryWidget.keyPressed(keyCode, scanCode, modifiers); + return this.colorEntryWidget.keyPressed(event); } } else { setFocused(null); if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { this.popupBlockEntity.addRawLine(this.currentRow + 1, this.popupBlockEntity.getRawLine(this.currentRow).substring( - MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.popupBlockEntity.getRawLine(this.currentRow).length()) + Mth.clamp(this.selectionManager.getCursorPos(), 0, this.popupBlockEntity.getRawLine(this.currentRow).length()) )); this.popupBlockEntity.setRawLine(this.currentRow, - this.popupBlockEntity.getRawLine(this.currentRow).substring(0, MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.popupBlockEntity.getRawLine(this.currentRow).length()) + this.popupBlockEntity.getRawLine(this.currentRow).substring(0, Mth.clamp(this.selectionManager.getCursorPos(), 0, this.popupBlockEntity.getRawLine(this.currentRow).length()) )); this.popupBlockEntity.renderDirty = true; ++this.currentRow; - this.selectionManager.moveCursorToStart(); + this.selectionManager.setCursorToStart(); return true; } else if (keyCode == GLFW.GLFW_KEY_UP) { this.currentRow = Math.max(this.currentRow - 1, 0); - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); return true; } else if (keyCode == GLFW.GLFW_KEY_DOWN) { this.currentRow = Math.min(this.currentRow + 1, (this.popupBlockEntity.lines.size() - 1)); - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); return true; - } else if (keyCode == GLFW.GLFW_KEY_BACKSPACE && this.currentRow > 0 && this.popupBlockEntity.lines.size() > 1 && this.selectionManager.getSelectionStart() == 0 && this.selectionManager.getSelectionEnd() == this.selectionManager.getSelectionStart()) { + } else if (keyCode == GLFW.GLFW_KEY_BACKSPACE && this.currentRow > 0 && this.popupBlockEntity.lines.size() > 1 && this.selectionManager.getCursorPos() == 0 && this.selectionManager.getSelectionPos() == this.selectionManager.getCursorPos()) { --this.currentRow; - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); deleteLine(); return true; - } else if (keyCode == GLFW.GLFW_KEY_DELETE && this.currentRow < this.popupBlockEntity.lines.size() - 1 && this.selectionManager.getSelectionEnd() == this.popupBlockEntity.getRawLine(this.currentRow).length()) { + } else if (keyCode == GLFW.GLFW_KEY_DELETE && this.currentRow < this.popupBlockEntity.lines.size() - 1 && this.selectionManager.getSelectionPos() == this.popupBlockEntity.getRawLine(this.currentRow).length()) { deleteLine(); return true; } else { try { - boolean val = this.selectionManager.handleSpecialKey(keyCode) || super.keyPressed(keyCode, scanCode, modifiers); - int selectionOffset = this.popupBlockEntity.getRawLine(this.currentRow).length() - this.selectionManager.getSelectionStart(); + boolean val = this.selectionManager.keyPressed(event) || super.keyPressed(event); + int selectionOffset = this.popupBlockEntity.getRawLine(this.currentRow).length() - this.selectionManager.getCursorPos(); // Find line feed characters and create proper newlines for (int i = 0; i < this.popupBlockEntity.lines.size(); ++i) { @@ -218,21 +222,21 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (lineFeedIndex >= 0) { this.popupBlockEntity.addRawLine(i + 1, this.popupBlockEntity.getRawLine(i).substring( - MathHelper.clamp(lineFeedIndex + 1, 0, this.popupBlockEntity.getRawLine(i).length()) + Mth.clamp(lineFeedIndex + 1, 0, this.popupBlockEntity.getRawLine(i).length()) )); this.popupBlockEntity.setRawLine(i, - this.popupBlockEntity.getRawLine(i).substring(0, MathHelper.clamp(lineFeedIndex, 0, this.popupBlockEntity.getRawLine(i).length()) + this.popupBlockEntity.getRawLine(i).substring(0, Mth.clamp(lineFeedIndex, 0, this.popupBlockEntity.getRawLine(i).length()) )); this.popupBlockEntity.renderDirty = true; ++this.currentRow; - this.selectionManager.putCursorAtEnd(); - this.selectionManager.moveCursor(-selectionOffset); + this.selectionManager.setCursorToEnd(); + this.selectionManager.moveByChars(-selectionOffset); } } return val; } catch (StringIndexOutOfBoundsException e) { e.printStackTrace(); - MinecraftClient.getInstance().setScreen(null); + Minecraft.getInstance().setScreen(null); return false; } } @@ -249,19 +253,21 @@ private void deleteLine() { } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double mouseX = event.x(); + double mouseY = event.y(); int topOffset = (int) (40 + 2 * this.width / 100F); - if (!this.titleEntryWidget.mouseClicked(mouseX, mouseY, button)) { + if (!this.titleEntryWidget.mouseClicked(event, doubleClick)) { this.titleEntryWidget.setFocused(false); } - if (!this.colorEntryWidget.mouseClicked(mouseX, mouseY, button)) { + if (!this.colorEntryWidget.mouseClicked(event, doubleClick)) { this.colorEntryWidget.setFocused(false); } if (mouseY > topOffset) { - this.currentRow = MathHelper.clamp((int) (mouseY - topOffset) / 12, 0, this.popupBlockEntity.lines.size() - 1); + this.currentRow = Mth.clamp((int) (mouseY - topOffset) / 12, 0, this.popupBlockEntity.lines.size() - 1); this.setFocused(null); String baseContents = this.popupBlockEntity.getRawLine(currentRow); - int baseContentsWidth = this.textRenderer.getWidth(baseContents); + int baseContentsWidth = this.font.width(baseContents); int contentsStart; int contentsEnd; switch (this.popupBlockEntity.textAlignment) { @@ -285,20 +291,20 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } if (mouseX <= contentsStart) { - this.selectionManager.moveCursorToStart(); + this.selectionManager.setCursorToStart(); } else if (mouseX >= contentsEnd) { - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); } else { int lastWidth = 0; for (int i = 1; i < baseContents.length(); i++) { String testContents = baseContents.substring(0, i); - int width = this.textRenderer.getWidth(testContents); + int width = this.font.width(testContents); int midpointWidth = (width + lastWidth) / 2; if (mouseX < contentsStart + midpointWidth) { - this.selectionManager.moveCursorTo(i - 1, false); + this.selectionManager.setCursorPos(i - 1, false); break; } else if (mouseX <= contentsStart + width) { - this.selectionManager.moveCursorTo(i, false); + this.selectionManager.setCursorPos(i, false); break; } lastWidth = width; @@ -306,7 +312,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } return true; } else { - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(event, doubleClick); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockViewScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockViewScreen.java index 098c154d..cedf2f20 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockViewScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/PopupBlockViewScreen.java @@ -1,7 +1,7 @@ package dev.hephaestus.glowcase.client.gui.screen.ingame; import dev.hephaestus.glowcase.block.entity.PopupBlockEntity; -import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.GuiGraphics; //TODO: multi-character selection at some point? it may be a bit complex but it'd be nice public class PopupBlockViewScreen extends GlowcaseScreen { @@ -12,24 +12,24 @@ public PopupBlockViewScreen(PopupBlockEntity popupBlockEntity) { } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (this.client != null) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { + if (this.minecraft != null) { super.render(context, mouseX, mouseY, delta); - context.getMatrices().pushMatrix(); - context.getMatrices().translate(0, 40 + 2 * this.width / 100F); + context.pose().pushMatrix(); + context.pose().translate(0, 40 + 2 * this.width / 100F); for (int i = 0; i < this.popupBlockEntity.lines.size(); ++i) { var text = this.popupBlockEntity.lines.get(i); - int lineWidth = this.textRenderer.getWidth(text); + int lineWidth = this.font.width(text); switch (this.popupBlockEntity.textAlignment) { - case LEFT -> context.drawTextWithShadow(client.textRenderer, text, this.width / 10, i * 12, this.popupBlockEntity.color); - case CENTER -> context.drawTextWithShadow(client.textRenderer, text, this.width / 2 - lineWidth / 2, i * 12, this.popupBlockEntity.color); - case RIGHT -> context.drawTextWithShadow(client.textRenderer, text, this.width - this.width / 10 - lineWidth, i * 12, this.popupBlockEntity.color); + case LEFT -> context.drawString(minecraft.font, text, this.width / 10, i * 12, this.popupBlockEntity.color); + case CENTER -> context.drawString(minecraft.font, text, this.width / 2 - lineWidth / 2, i * 12, this.popupBlockEntity.color); + case RIGHT -> context.drawString(minecraft.font, text, this.width - this.width / 10 - lineWidth, i * 12, this.popupBlockEntity.color); } } - context.getMatrices().popMatrix(); + context.pose().popMatrix(); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/RecipeBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/RecipeBlockEditScreen.java index 348800c3..85e3cd08 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/RecipeBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/RecipeBlockEditScreen.java @@ -11,24 +11,26 @@ import dev.hephaestus.glowcase.client.util.EmiClientUtils; import dev.hephaestus.glowcase.util.EmiUtils; import dev.hephaestus.glowcase.util.RequiresEmiLoaded; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; import org.jetbrains.annotations.NotNull; import org.joml.Matrix3x2fStack; import java.util.List; import java.util.concurrent.atomic.AtomicReference; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; public class RecipeBlockEditScreen extends GlowcaseScreen { private static final List NO_SUGGESTIONS = List.of(); private final RecipeBlockEntity recipeBlockEntity; - private TextFieldWidget recipeWidget; - private TextFieldWidget rotationXWidget; - private TextFieldWidget rotationYWidget; + private EditBox recipeWidget; + private EditBox rotationXWidget; + private EditBox rotationYWidget; private SuggestionListWidget suggestionWidget; @@ -36,7 +38,7 @@ public class RecipeBlockEditScreen extends GlowcaseScreen { @NotNull private final AtomicReference glowcaseWidgetHolder = new AtomicReference<>(null); - private ButtonWidget zOffsetToggle; + private Button zOffsetToggle; private int fontHeight = -1; private int baseY; @@ -49,100 +51,100 @@ public RecipeBlockEditScreen(RecipeBlockEntity recipeBlockEntity) { public void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; if (fontHeight == -1) { - fontHeight = this.client.textRenderer.fontHeight; + fontHeight = this.minecraft.font.lineHeight; baseY = height / 2 - ((2 * fontHeight + 95) / 2) + fontHeight - (GlowcaseClient.EMI_LOADED ? 46 : 0); } - this.recipeWidget = new GlowcaseTextFieldWidget(this.client.textRenderer, width / 2 - 150, baseY + 10, 300, 20, Text.empty()); + this.recipeWidget = new GlowcaseTextFieldWidget(this.minecraft.font, width / 2 - 150, baseY + 10, 300, 20, Component.empty()); this.recipeWidget.setMaxLength(1024); - this.recipeWidget.setText(recipeBlockEntity.recipe); + this.recipeWidget.setValue(recipeBlockEntity.recipe); - this.rotationXWidget = new TextFieldWidget(this.client.textRenderer, (width - 145) / 2, baseY + fontHeight + 45, 70, 20, Text.empty()); + this.rotationXWidget = new EditBox(this.minecraft.font, (width - 145) / 2, baseY + fontHeight + 45, 70, 20, Component.empty()); this.rotationXWidget.setMaxLength(1024); - this.rotationXWidget.setText(Float.toString(recipeBlockEntity.rotationX)); - this.rotationXWidget.setChangedListener(s -> { + this.rotationXWidget.setValue(Float.toString(recipeBlockEntity.rotationX)); + this.rotationXWidget.setResponder(s -> { if (Floats.tryParse(s) instanceof Float parsed) { recipeBlockEntity.rotationX = parsed; } }); - this.rotationYWidget = new TextFieldWidget(this.client.textRenderer, (width - 145) / 2 + 75, baseY + fontHeight + 45, 70, 20, Text.empty()); + this.rotationYWidget = new EditBox(this.minecraft.font, (width - 145) / 2 + 75, baseY + fontHeight + 45, 70, 20, Component.empty()); this.rotationYWidget.setMaxLength(1024); - this.rotationYWidget.setText(Float.toString(recipeBlockEntity.rotationY)); - this.rotationYWidget.setChangedListener(s -> { + this.rotationYWidget.setValue(Float.toString(recipeBlockEntity.rotationY)); + this.rotationYWidget.setResponder(s -> { if (Floats.tryParse(s) instanceof Float parsed) { recipeBlockEntity.rotationY = parsed; } }); - this.zOffsetToggle = ButtonWidget.builder(Text.literal(this.recipeBlockEntity.zOffset.name()), action -> { + this.zOffsetToggle = Button.builder(Component.literal(this.recipeBlockEntity.zOffset.name()), action -> { switch (recipeBlockEntity.zOffset) { case FRONT -> recipeBlockEntity.zOffset = TextBlockEntity.ZOffset.CENTER; case CENTER -> recipeBlockEntity.zOffset = TextBlockEntity.ZOffset.BACK; case BACK -> recipeBlockEntity.zOffset = TextBlockEntity.ZOffset.FRONT; } - this.zOffsetToggle.setMessage(Text.literal(this.recipeBlockEntity.zOffset.name())); - }).dimensions(width / 2 - 75, baseY + fontHeight + 75, 150, 20).build(); + this.zOffsetToggle.setMessage(Component.literal(this.recipeBlockEntity.zOffset.name())); + }).bounds(width / 2 - 75, baseY + fontHeight + 75, 150, 20).build(); - suggestionWidget = SuggestionListWidget.forTextField(recipeWidget, client.textRenderer, Identifier::toString); + suggestionWidget = SuggestionListWidget.forTextField(recipeWidget, minecraft.font, Identifier::toString); - recipeWidget.setChangedListener((text) -> { - if (Identifier.tryParse(this.recipeWidget.getText()) != null) { - this.recipeBlockEntity.recipe = this.recipeWidget.getText(); + recipeWidget.setResponder((text) -> { + if (Identifier.tryParse(this.recipeWidget.getValue()) != null) { + this.recipeBlockEntity.recipe = this.recipeWidget.getValue(); } if (GlowcaseClient.EMI_LOADED) { suggestionWidget.updateSuggestions(EmiUtils.RECIPE_LIST.get(), text, false, this); - EmiClientUtils.updateWidgetHolder(recipeWidget.getText(), glowcaseWidgetHolder); + EmiClientUtils.updateWidgetHolder(recipeWidget.getValue(), glowcaseWidgetHolder); } }); - this.addDrawableChild(this.recipeWidget); - this.addDrawableChild(this.rotationXWidget); - this.addDrawableChild(this.rotationYWidget); - this.addDrawableChild(this.zOffsetToggle); + this.addRenderableWidget(this.recipeWidget); + this.addRenderableWidget(this.rotationXWidget); + this.addRenderableWidget(this.rotationYWidget); + this.addRenderableWidget(this.zOffsetToggle); if (GlowcaseClient.EMI_LOADED && glowcaseWidgetHolder.get() == null) { - EmiClientUtils.updateWidgetHolder(recipeWidget.getText(), glowcaseWidgetHolder); + EmiClientUtils.updateWidgetHolder(recipeWidget.getValue(), glowcaseWidgetHolder); } } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); - if (this.client == null) return; + if (this.minecraft == null) return; if (fontHeight == -1) { - fontHeight = this.client.textRenderer.fontHeight; + fontHeight = this.minecraft.font.lineHeight; baseY = height / 2 - ((2 * fontHeight + 95) / 2) + fontHeight - 46; } - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.recipe"), - width / 2 - (this.client.textRenderer.getWidth(Text.translatable("gui.glowcase.recipe")) / 2), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.recipe"), + width / 2 - (this.minecraft.font.width(Component.translatable("gui.glowcase.recipe")) / 2), baseY - fontHeight, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.pitch"), - ((width - 145) / 2) + 35 - (this.client.textRenderer.getWidth(Text.translatable("gui.glowcase.pitch")) / 2), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.pitch"), + ((width - 145) / 2) + 35 - (this.minecraft.font.width(Component.translatable("gui.glowcase.pitch")) / 2), baseY + 40, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.yaw"), - ((width - 145) / 2) + 75 + 35 - (this.client.textRenderer.getWidth(Text.translatable("gui.glowcase.yaw")) / 2), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.yaw"), + ((width - 145) / 2) + 75 + 35 - (this.minecraft.font.width(Component.translatable("gui.glowcase.yaw")) / 2), baseY + 40, 0xFFFFFFFF ); @@ -158,7 +160,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { int holderWidth = EmiClientUtils.getHolderWidth(widgetHolder); int holderHeight = EmiClientUtils.getHolderHeight(widgetHolder); - Matrix3x2fStack matrixStack = context.getMatrices(); + Matrix3x2fStack matrixStack = context.pose(); matrixStack.pushMatrix(); matrixStack.translate(width / 2f - holderWidth / 2f, baseYForRecipe + spaceForRecipe / 2f - holderHeight / 2f); @@ -167,26 +169,27 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { matrixStack.popMatrix(); } } - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double mouseX = event.x(); + double mouseY = event.y(); if (suggestionWidget.isMouseOver(mouseX, mouseY) && recipeWidget.isFocused()) { - return suggestionWidget.mouseClicked(mouseX, mouseY, button); + return suggestionWidget.mouseClicked(event, doubleClick); } else { suggestionWidget.updateSuggestions(NO_SUGGESTIONS, "", this); } - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(event, doubleClick); } @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) { if (suggestionWidget.draggingScrollbar) { - if (suggestionWidget.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) + if (suggestionWidget.mouseDragged(event, dx, dy)) return true; } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + return super.mouseDragged(event, dx, dy); } @Override @@ -200,18 +203,18 @@ public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmou } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (suggestionWidget.keyPressed(keyCode, scanCode, modifiers)) { + public boolean keyPressed(KeyEvent event) { + if (suggestionWidget.keyPressed(event)) { return true; } - return super.keyPressed(keyCode, scanCode, modifiers); + return super.keyPressed(event); } @Override - public void close() { - recipeBlockEntity.setRecipe(recipeWidget.getText()); + public void onClose() { + recipeBlockEntity.setRecipe(recipeWidget.getValue()); C2SEditRecipeBlock.of(recipeBlockEntity).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ScreenBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ScreenBlockEditScreen.java index 96804fb2..f150cb3c 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ScreenBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/ScreenBlockEditScreen.java @@ -4,32 +4,36 @@ import dev.hephaestus.glowcase.block.entity.ScreenBlockEntity; import dev.hephaestus.glowcase.packet.C2SEditScreenBlock; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.gui.widget.*; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.Checkbox; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import org.lwjgl.glfw.GLFW; public class ScreenBlockEditScreen extends GlowcaseScreen { private final ScreenBlockEntity screenBlockEntity; - private TextFieldWidget widthEntryWidget; - private TextFieldWidget heightEntryWidget; - private ButtonWidget zOffsetToggle; - private ButtonWidget[] alignment; + private EditBox widthEntryWidget; + private EditBox heightEntryWidget; + private Button zOffsetToggle; + private Button[] alignment; - private CheckboxWidget renderBackfaceWidget; - private CheckboxWidget einkCheckWidget; - private CheckboxWidget stretchCheckWidget; + private Checkbox renderBackfaceWidget; + private Checkbox einkCheckWidget; + private Checkbox stretchCheckWidget; - private TextFieldWidget urlEntryWidget; - private TextFieldWidget altEntryWidget; + private EditBox urlEntryWidget; + private EditBox altEntryWidget; - private TextFieldWidget yawEntryWidget; - private TextFieldWidget pitchEntryWidget; + private EditBox yawEntryWidget; + private EditBox pitchEntryWidget; - private TextFieldWidget offsetXField; - private TextFieldWidget offsetYField; - private TextFieldWidget offsetZField; + private EditBox offsetXField; + private EditBox offsetYField; + private EditBox offsetZField; public ScreenBlockEditScreen(ScreenBlockEntity screenBlockEntity) { this.screenBlockEntity = screenBlockEntity; @@ -38,7 +42,7 @@ public ScreenBlockEditScreen(ScreenBlockEntity screenBlockEntity) { @Override protected void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; // dimension constants int gap = 5; @@ -47,33 +51,33 @@ protected void init() { int fieldWidth = (availableWidth - (2 * gap)) / 3; int fieldY = (height / 2) - 110; - this.widthEntryWidget = new TextFieldWidget(this.client.textRenderer, leftX, fieldY + 40 + 20 + 5, 2 * leftX, 20, Text.empty()); - this.widthEntryWidget.setText(""+this.screenBlockEntity.width); - this.widthEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.width")); - this.widthEntryWidget.setChangedListener(string -> { + this.widthEntryWidget = new EditBox(this.minecraft.font, leftX, fieldY + 40 + 20 + 5, 2 * leftX, 20, Component.empty()); + this.widthEntryWidget.setValue(""+this.screenBlockEntity.width); + this.widthEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.width")); + this.widthEntryWidget.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) screenBlockEntity.width = parsed; }); - MutableText timesLiteral = Text.literal("×"); - TextWidget timesLabel = new TextWidget(3 * leftX + gap, fieldY + 40 + 20 + 5, textRenderer.getWidth(timesLiteral), 20, timesLiteral, this.client.textRenderer); + MutableComponent timesLiteral = Component.literal("×"); + StringWidget timesLabel = new StringWidget(3 * leftX + gap, fieldY + 40 + 20 + 5, font.width(timesLiteral), 20, timesLiteral, this.minecraft.font); - this.heightEntryWidget = new TextFieldWidget(this.client.textRenderer, 3 * leftX + 10 + textRenderer.getWidth(timesLiteral), fieldY + 40 + 20 + 5, 2 * leftX, 20, Text.empty()); - this.heightEntryWidget.setText(""+this.screenBlockEntity.height); - this.heightEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.height")); - this.heightEntryWidget.setChangedListener(string -> { + this.heightEntryWidget = new EditBox(this.minecraft.font, 3 * leftX + 10 + font.width(timesLiteral), fieldY + 40 + 20 + 5, 2 * leftX, 20, Component.empty()); + this.heightEntryWidget.setValue(""+this.screenBlockEntity.height); + this.heightEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.height")); + this.heightEntryWidget.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) screenBlockEntity.height = parsed; }); - this.yawEntryWidget = new TextFieldWidget(this.client.textRenderer, leftX, fieldY + 40, (4 * leftX + 10 + textRenderer.getWidth(timesLiteral)) / 2 - 5, 20, Text.empty()); + this.yawEntryWidget = new EditBox(this.minecraft.font, leftX, fieldY + 40, (4 * leftX + 10 + font.width(timesLiteral)) / 2 - 5, 20, Component.empty()); if (this.screenBlockEntity.yaw == 0.0f) { - this.yawEntryWidget.setText(""); - this.yawEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.yaw")); + this.yawEntryWidget.setValue(""); + this.yawEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.yaw")); } else { - this.yawEntryWidget.setText(String.valueOf(this.screenBlockEntity.yaw)); + this.yawEntryWidget.setValue(String.valueOf(this.screenBlockEntity.yaw)); } - this.yawEntryWidget.setChangedListener(string -> { + this.yawEntryWidget.setResponder(string -> { if (string.isEmpty()) { screenBlockEntity.yaw = 0f; } else if (Floats.tryParse(string) instanceof Float parsed) { @@ -81,14 +85,14 @@ protected void init() { } }); - this.pitchEntryWidget = new TextFieldWidget(this.client.textRenderer, leftX + (4 * leftX + 10 + textRenderer.getWidth(timesLiteral)) / 2, fieldY + 40, (4 * leftX + 10 + textRenderer.getWidth(timesLiteral)) / 2, 20, Text.empty()); + this.pitchEntryWidget = new EditBox(this.minecraft.font, leftX + (4 * leftX + 10 + font.width(timesLiteral)) / 2, fieldY + 40, (4 * leftX + 10 + font.width(timesLiteral)) / 2, 20, Component.empty()); if (this.screenBlockEntity.pitch == 0.0f) { - this.pitchEntryWidget.setText(""); - this.pitchEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.pitch")); + this.pitchEntryWidget.setValue(""); + this.pitchEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.pitch")); } else { - this.pitchEntryWidget.setText(String.valueOf(this.screenBlockEntity.pitch)); + this.pitchEntryWidget.setValue(String.valueOf(this.screenBlockEntity.pitch)); } - this.pitchEntryWidget.setChangedListener(string -> { + this.pitchEntryWidget.setResponder(string -> { if (string.isEmpty()) { screenBlockEntity.pitch = 0f; } else if (Floats.tryParse(string) instanceof Float parsed) { @@ -96,32 +100,32 @@ protected void init() { } }); - TextWidget offsetXLabel = new TextWidget(leftX, fieldY - 5, fieldWidth, 20, Text.translatable("gui.glowcase.x_offset_label"), this.client.textRenderer); - TextWidget offsetYLabel = new TextWidget(leftX + fieldWidth + gap, fieldY - 5, fieldWidth, 20, Text.translatable("gui.glowcase.y_offset_label"), this.client.textRenderer); - TextWidget offsetZLabel = new TextWidget(leftX + 2 * (fieldWidth + gap), fieldY - 5, fieldWidth, 20, Text.translatable("gui.glowcase.z_offset_label"), this.client.textRenderer); + StringWidget offsetXLabel = new StringWidget(leftX, fieldY - 5, fieldWidth, 20, Component.translatable("gui.glowcase.x_offset_label"), this.minecraft.font); + StringWidget offsetYLabel = new StringWidget(leftX + fieldWidth + gap, fieldY - 5, fieldWidth, 20, Component.translatable("gui.glowcase.y_offset_label"), this.minecraft.font); + StringWidget offsetZLabel = new StringWidget(leftX + 2 * (fieldWidth + gap), fieldY - 5, fieldWidth, 20, Component.translatable("gui.glowcase.z_offset_label"), this.minecraft.font); - this.offsetXField = new TextFieldWidget(this.client.textRenderer, leftX, fieldY + 15, fieldWidth, 20, Text.empty()); - this.offsetXField.setText("" + this.screenBlockEntity.preciseX); - this.offsetXField.setChangedListener(string -> { + this.offsetXField = new EditBox(this.minecraft.font, leftX, fieldY + 15, fieldWidth, 20, Component.empty()); + this.offsetXField.setValue("" + this.screenBlockEntity.preciseX); + this.offsetXField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) screenBlockEntity.preciseX = parsed; }); - this.offsetYField = new TextFieldWidget(this.client.textRenderer, leftX + fieldWidth + gap, fieldY + 15, fieldWidth, 20, Text.empty()); - this.offsetYField.setText("" + this.screenBlockEntity.preciseY); - this.offsetYField.setChangedListener(string -> { + this.offsetYField = new EditBox(this.minecraft.font, leftX + fieldWidth + gap, fieldY + 15, fieldWidth, 20, Component.empty()); + this.offsetYField.setValue("" + this.screenBlockEntity.preciseY); + this.offsetYField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) screenBlockEntity.preciseY = parsed; }); - this.offsetZField = new TextFieldWidget(this.client.textRenderer, leftX + 2 * (fieldWidth + gap), fieldY + 15, fieldWidth, 20, Text.empty()); - this.offsetZField.setText("" + this.screenBlockEntity.preciseZ); - this.offsetZField.setChangedListener(string -> { + this.offsetZField = new EditBox(this.minecraft.font, leftX + 2 * (fieldWidth + gap), fieldY + 15, fieldWidth, 20, Component.empty()); + this.offsetZField.setValue("" + this.screenBlockEntity.preciseZ); + this.offsetZField.setResponder(string -> { if (Floats.tryParse(string) instanceof Float parsed) screenBlockEntity.preciseZ = parsed; }); - this.zOffsetToggle = ButtonWidget.builder(Text.translatable(switch (this.screenBlockEntity.zOffset) { + this.zOffsetToggle = Button.builder(Component.translatable(switch (this.screenBlockEntity.zOffset) { case NEGATIVE -> "gui.glowcase.back"; case NULL -> "gui.glowcase.center"; case POSITIVE -> "gui.glowcase.front"; @@ -131,12 +135,12 @@ protected void init() { case NULL -> screenBlockEntity.zOffset = ScreenBlockEntity.Offset.NEGATIVE; case NEGATIVE -> screenBlockEntity.zOffset = ScreenBlockEntity.Offset.POSITIVE; } - this.zOffsetToggle.setMessage(Text.translatable(switch (this.screenBlockEntity.zOffset) { + this.zOffsetToggle.setMessage(Component.translatable(switch (this.screenBlockEntity.zOffset) { case NEGATIVE -> "gui.glowcase.back"; case NULL -> "gui.glowcase.center"; case POSITIVE -> "gui.glowcase.front"; })); - }).dimensions(7 * width / 10, height / 2 - 70, 2 * width / 10, 20).build(); + }).bounds(7 * width / 10, height / 2 - 70, 2 * width / 10, 20).build(); { // We create a button for each alignment possibility of the screen on a 2D canvas (top-left to bottom-right) int xoff = 7 * width / 10; @@ -144,28 +148,28 @@ protected void init() { int sub_width = 2 * width / 10; - this.addDrawableChild(new TextWidget( + this.addRenderableWidget(new StringWidget( xoff, yoff, - sub_width, this.client.textRenderer.fontHeight, - Text.translatableWithFallback("gui.glowcase.screen.alignment", "%s", this.screenBlockEntity.macaddress), - this.client.textRenderer) + sub_width, this.minecraft.font.lineHeight, + Component.translatableWithFallback("gui.glowcase.screen.alignment", "%s", this.screenBlockEntity.macaddress), + this.minecraft.font) ); xoff += sub_width/2 - (15 * 2 + 10)/2; - yoff += this.client.textRenderer.fontHeight + 5; + yoff += this.minecraft.font.lineHeight + 5; int count = 0; - alignment = new ButtonWidget[9]; + alignment = new Button[9]; for (int y = 0; y < 3; y++) for (int x = 0; x < 3; x++) { - ButtonWidget button = ButtonWidget.builder(Text.literal(""), action -> { - for (ButtonWidget buttonWidget : alignment) + Button button = Button.builder(Component.literal(""), action -> { + for (Button buttonWidget : alignment) buttonWidget.active = true; action.active = false; // Update x and y offset int cur_x = -1, cur_y = 0; - for (ButtonWidget buttonWidget : alignment) { + for (Button buttonWidget : alignment) { cur_x++; if (cur_x > 2) { cur_x = 0; @@ -178,7 +182,7 @@ protected void init() { break; } } - }).dimensions(xoff + (x*15), yoff + (y*15), 10, 10).build(); + }).bounds(xoff + (x*15), yoff + (y*15), 10, 10).build(); // Current Alignment if (screenBlockEntity.xOffset.offset+1 == x && screenBlockEntity.yOffset.offset+1 == y) @@ -189,117 +193,120 @@ protected void init() { } } - this.renderBackfaceWidget = CheckboxWidget.builder(Text.translatable("gui.glowcase.screen.backface"), this.client.textRenderer) - .checked(this.screenBlockEntity.renderBackface) - .callback((checkbox, checked) -> this.screenBlockEntity.renderBackface = checked) + this.renderBackfaceWidget = Checkbox.builder(Component.translatable("gui.glowcase.screen.backface"), this.minecraft.font) + .selected(this.screenBlockEntity.renderBackface) + .onValueChange((checkbox, checked) -> this.screenBlockEntity.renderBackface = checked) .pos(width / 10, height / 2 - 30 + 11) .build(); - this.einkCheckWidget = CheckboxWidget.builder(Text.translatable("gui.glowcase.screen.eink"), this.client.textRenderer) - .checked(this.screenBlockEntity.eink) - .callback((checkbox, checked) -> this.screenBlockEntity.eink = checked) + this.einkCheckWidget = Checkbox.builder(Component.translatable("gui.glowcase.screen.eink"), this.minecraft.font) + .selected(this.screenBlockEntity.eink) + .onValueChange((checkbox, checked) -> this.screenBlockEntity.eink = checked) .pos(width / 10, height / 2 - 10 + 11) .build(); - this.stretchCheckWidget = CheckboxWidget.builder(Text.translatable("gui.glowcase.screen.stretch"), this.client.textRenderer) - .checked(this.screenBlockEntity.stretch) - .callback((checkbox, checked) -> this.screenBlockEntity.stretch = checked) + this.stretchCheckWidget = Checkbox.builder(Component.translatable("gui.glowcase.screen.stretch"), this.minecraft.font) + .selected(this.screenBlockEntity.stretch) + .onValueChange((checkbox, checked) -> this.screenBlockEntity.stretch = checked) .pos(width / 10, height / 2 + 10 + 11) .build(); - this.urlEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 10, height / 2 + 45, 7 * width / 10, 20, Text.empty()); + this.urlEntryWidget = new EditBox(this.minecraft.font, width / 10, height / 2 + 45, 7 * width / 10, 20, Component.empty()); this.urlEntryWidget.setMaxLength(ScreenBlockEntity.URL_MAX_LENGTH); - this.urlEntryWidget.setText(this.screenBlockEntity.url); - this.urlEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.url")); + this.urlEntryWidget.setValue(this.screenBlockEntity.url); + this.urlEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.url")); // We don't change the url on the fly here as that would cause many fetch requests which we don't want - this.altEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 10, height / 2 + 65 + 5, 7 * width / 10, 40, Text.empty()); + this.altEntryWidget = new EditBox(this.minecraft.font, width / 10, height / 2 + 65 + 5, 7 * width / 10, 40, Component.empty()); this.altEntryWidget.setMaxLength(ScreenBlockEntity.ALT_MAX_LENGTH); - this.altEntryWidget.setText(this.screenBlockEntity.alt); - this.altEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.alt")); - this.altEntryWidget.setChangedListener(string -> screenBlockEntity.alt = string); - - if (this.client.options.advancedItemTooltips) - this.addDrawableChild(new TextWidget( - 3, height - this.client.textRenderer.fontHeight - 1, - width, this.client.textRenderer.fontHeight, - Text.translatableWithFallback("gui.glowcase.screen.mac_address", "%s", this.screenBlockEntity.macaddress), - this.client.textRenderer).alignLeft().setTextColor(0x696969) + this.altEntryWidget.setValue(this.screenBlockEntity.alt); + this.altEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.alt")); + this.altEntryWidget.setResponder(string -> screenBlockEntity.alt = string); + + if (this.minecraft.options.advancedItemTooltips) + this.addRenderableWidget(new StringWidget( + 3, height - this.minecraft.font.lineHeight - 1, + width, this.minecraft.font.lineHeight, + Component.translatableWithFallback("gui.glowcase.screen.mac_address", "%s", this.screenBlockEntity.macaddress), + this.minecraft.font) +// FIXME these seem to no longer exist +// .alignLeft().setColor(0x696969) ); - this.addDrawableChild(this.widthEntryWidget); - this.addDrawableChild(timesLabel); - this.addDrawableChild(this.heightEntryWidget); - this.addDrawableChild(this.zOffsetToggle); + this.addRenderableWidget(this.widthEntryWidget); + this.addRenderableWidget(timesLabel); + this.addRenderableWidget(this.heightEntryWidget); + this.addRenderableWidget(this.zOffsetToggle); - this.addDrawableChild(offsetXLabel); - this.addDrawableChild(offsetYLabel); - this.addDrawableChild(offsetZLabel); - this.addDrawableChild(offsetXField); - this.addDrawableChild(offsetYField); - this.addDrawableChild(offsetZField); + this.addRenderableWidget(offsetXLabel); + this.addRenderableWidget(offsetYLabel); + this.addRenderableWidget(offsetZLabel); + this.addRenderableWidget(offsetXField); + this.addRenderableWidget(offsetYField); + this.addRenderableWidget(offsetZField); - for (ButtonWidget buttonWidget : alignment) - this.addDrawableChild(buttonWidget); + for (Button buttonWidget : alignment) + this.addRenderableWidget(buttonWidget); - this.addDrawableChild(this.renderBackfaceWidget); - this.addDrawableChild(this.einkCheckWidget); - this.addDrawableChild(this.stretchCheckWidget); + this.addRenderableWidget(this.renderBackfaceWidget); + this.addRenderableWidget(this.einkCheckWidget); + this.addRenderableWidget(this.stretchCheckWidget); - this.addDrawableChild(this.urlEntryWidget); - this.addDrawableChild(this.altEntryWidget); + this.addRenderableWidget(this.urlEntryWidget); + this.addRenderableWidget(this.altEntryWidget); - this.addDrawableChild(this.yawEntryWidget); - this.addDrawableChild(this.pitchEntryWidget); + this.addRenderableWidget(this.yawEntryWidget); + this.addRenderableWidget(this.pitchEntryWidget); } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + public boolean keyPressed(KeyEvent event) { + int keyCode = event.key(); if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER || keyCode == GLFW.GLFW_KEY_ESCAPE) { - this.close(); + this.onClose(); return true; - } else if (this.widthEntryWidget.isActive()) { - return this.widthEntryWidget.keyPressed(keyCode, scanCode, modifiers); - } else if (this.heightEntryWidget.isActive()) { - return this.heightEntryWidget.keyPressed(keyCode, scanCode, modifiers); - } else if (this.urlEntryWidget.isActive()) { - return this.urlEntryWidget.keyPressed(keyCode, scanCode, modifiers); - } else if (this.altEntryWidget.isActive()) { - return this.altEntryWidget.keyPressed(keyCode, scanCode, modifiers); - } else if (this.offsetXField.isActive()) { - return this.offsetXField.keyPressed(keyCode, scanCode, modifiers); - } else if (this.offsetYField.isActive()) { - return this.offsetYField.keyPressed(keyCode, scanCode, modifiers); - } else if (this.offsetZField.isActive()) { - return this.offsetZField.keyPressed(keyCode, scanCode, modifiers); - } else if (this.pitchEntryWidget.isActive()) { - return this.pitchEntryWidget.keyPressed(keyCode, scanCode, modifiers); - } else if (this.yawEntryWidget.isActive()) { - return this.yawEntryWidget.keyPressed(keyCode, scanCode, modifiers); + } else if (this.widthEntryWidget.canConsumeInput()) { + return this.widthEntryWidget.keyPressed(event); + } else if (this.heightEntryWidget.canConsumeInput()) { + return this.heightEntryWidget.keyPressed(event); + } else if (this.urlEntryWidget.canConsumeInput()) { + return this.urlEntryWidget.keyPressed(event); + } else if (this.altEntryWidget.canConsumeInput()) { + return this.altEntryWidget.keyPressed(event); + } else if (this.offsetXField.canConsumeInput()) { + return this.offsetXField.keyPressed(event); + } else if (this.offsetYField.canConsumeInput()) { + return this.offsetYField.keyPressed(event); + } else if (this.offsetZField.canConsumeInput()) { + return this.offsetZField.keyPressed(event); + } else if (this.pitchEntryWidget.canConsumeInput()) { + return this.pitchEntryWidget.keyPressed(event); + } else if (this.yawEntryWidget.canConsumeInput()) { + return this.yawEntryWidget.keyPressed(event); } else { return false; } } @Override - public void close() { - Float parsedX = Floats.tryParse(this.offsetXField.getText()); - Float parsedY = Floats.tryParse(this.offsetYField.getText()); - Float parsedZ = Floats.tryParse(this.offsetZField.getText()); + public void onClose() { + Float parsedX = Floats.tryParse(this.offsetXField.getValue()); + Float parsedY = Floats.tryParse(this.offsetYField.getValue()); + Float parsedZ = Floats.tryParse(this.offsetZField.getValue()); screenBlockEntity.preciseX = (parsedX != null) ? parsedX : 0f; screenBlockEntity.preciseY = (parsedY != null) ? parsedY : 0f; screenBlockEntity.preciseZ = (parsedZ != null) ? parsedZ : 0f; - screenBlockEntity.eink = einkCheckWidget.isChecked(); - screenBlockEntity.stretch = stretchCheckWidget.isChecked(); + screenBlockEntity.eink = einkCheckWidget.selected(); + screenBlockEntity.stretch = stretchCheckWidget.selected(); screenBlockEntity.setImage( - urlEntryWidget.getText(), - altEntryWidget.getText(), + urlEntryWidget.getValue(), + altEntryWidget.getValue(), null ); C2SEditScreenBlock.of(screenBlockEntity).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SoundPlayerBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SoundPlayerBlockEditScreen.java index acc32278..e7eb2b8f 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SoundPlayerBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SoundPlayerBlockEditScreen.java @@ -4,14 +4,16 @@ import dev.hephaestus.glowcase.client.gui.widget.ingame.GlowcaseTextFieldWidget; import dev.hephaestus.glowcase.client.gui.widget.ingame.SuggestionListWidget; import dev.hephaestus.glowcase.client.gui.widget.ingame.Vec3FieldsWidget; -import dev.hephaestus.glowcase.util.ParseUtil; import dev.hephaestus.glowcase.packet.C2SEditSoundBlock; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.registry.Registries; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; +import dev.hephaestus.glowcase.util.ParseUtil; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; import java.util.ArrayList; import java.util.List; @@ -22,16 +24,16 @@ public class SoundPlayerBlockEditScreen extends GlowcaseScreen { private final SoundPlayerBlockEntity soundBlock; - private TextFieldWidget soundId; - private ButtonWidget categoryButton; - private ButtonWidget cancelOthersButton; + private EditBox soundId; + private Button categoryButton; + private Button cancelOthersButton; - private TextFieldWidget volume; - private TextFieldWidget pitch; - private TextFieldWidget repeatDelay; + private EditBox volume; + private EditBox pitch; + private EditBox repeatDelay; - private TextFieldWidget distance; - private ButtonWidget relativeButton; + private EditBox distance; + private Button relativeButton; private Vec3FieldsWidget offset; private SuggestionListWidget suggestionWidget; @@ -44,148 +46,152 @@ public SoundPlayerBlockEditScreen(SoundPlayerBlockEntity soundBlock) { @Override protected void init() { super.init(); - Objects.requireNonNull(this.client); + Objects.requireNonNull(this.minecraft); // RegistryWrapper.WrapperLookup lookup = Objects.requireNonNull(client.world).getRegistryManager(); this.soundId = new GlowcaseTextFieldWidget( - this.client.textRenderer, + this.minecraft.font, width / 10, height / 2 - 110, 8 * width / 10, 20, - Text.empty()); + Component.empty()); this.soundId.setMaxLength(1024); - this.soundId.setText(soundBlock.soundId.toString()); - this.addDrawableChild(soundId); + this.soundId.setValue(soundBlock.soundId.toString()); + this.addRenderableWidget(soundId); - this.categoryButton = new ButtonWidget.Builder(Text.stringifiedTranslatable("gui.glowcase.sound_category", this.soundBlock.category.getName()), (action) -> { + this.categoryButton = new Button.Builder(Component.translatableEscape("gui.glowcase.sound_category", this.soundBlock.category.getName()), (action) -> { soundBlock.cycleCategory(); - this.categoryButton.setMessage(Text.stringifiedTranslatable("gui.glowcase.sound_category", this.soundBlock.category.getName())); - }).dimensions(width / 10, height / 2 - 60, (4 * width / 10) - 6, 20).build(); - this.addDrawableChild(this.categoryButton); + this.categoryButton.setMessage(Component.translatableEscape("gui.glowcase.sound_category", this.soundBlock.category.getName())); + }).bounds(width / 10, height / 2 - 60, (4 * width / 10) - 6, 20).build(); + this.addRenderableWidget(this.categoryButton); - this.cancelOthersButton = new ButtonWidget.Builder(Text.of(Boolean.toString(soundBlock.cancelOthers)), (action) -> { + this.cancelOthersButton = new Button.Builder(Component.nullToEmpty(Boolean.toString(soundBlock.cancelOthers)), (action) -> { soundBlock.cancelOthers = !soundBlock.cancelOthers; - this.cancelOthersButton.setMessage(Text.of(Boolean.toString(soundBlock.cancelOthers))); - }).dimensions(width / 10 + (4 * width / 10) + 6, height / 2 - 60, (4 * width / 10) - 6, 20).build(); - this.addDrawableChild(this.cancelOthersButton); + this.cancelOthersButton.setMessage(Component.nullToEmpty(Boolean.toString(soundBlock.cancelOthers))); + }).bounds(width / 10 + (4 * width / 10) + 6, height / 2 - 60, (4 * width / 10) - 6, 20).build(); + this.addRenderableWidget(this.cancelOthersButton); - this.volume = new TextFieldWidget( - this.client.textRenderer, + this.volume = new EditBox( + this.minecraft.font, width / 10, height / 2 - 10, (4 * width / 10) - 6, 20, - Text.empty()); + Component.empty()); this.volume.setMaxLength(16); - this.volume.setText(String.valueOf(soundBlock.volume)); - this.volume.setTextPredicate(ParseUtil::canParseDouble); - this.addDrawableChild(this.volume); + this.volume.setValue(String.valueOf(soundBlock.volume)); + //FIXME 26.1 +// this.volume.setFilter(ParseUtil::canParseDouble); + this.addRenderableWidget(this.volume); - this.pitch = new TextFieldWidget( - this.client.textRenderer, + this.pitch = new EditBox( + this.minecraft.font, width / 10 + (4 * width / 10) + 6, height / 2 - 10, (4 * width / 10) - 6, 20, - Text.empty()); + Component.empty()); this.pitch.setMaxLength(16); - this.pitch.setText(String.valueOf(soundBlock.pitch)); - this.pitch.setTextPredicate(ParseUtil::canParseDouble); - this.addDrawableChild(this.pitch); + this.pitch.setValue(String.valueOf(soundBlock.pitch)); + //FIXME 26.1 +// this.pitch.setFilter(ParseUtil::canParseDouble); + this.addRenderableWidget(this.pitch); - this.repeatDelay = new TextFieldWidget( - this.client.textRenderer, + this.repeatDelay = new EditBox( + this.minecraft.font, width / 10, height / 2 + 40, (4 * width / 10) - 6, 20, - Text.empty()); + Component.empty()); this.repeatDelay.setMaxLength(16); - this.repeatDelay.setText(String.valueOf(soundBlock.repeatDelay)); - this.repeatDelay.setTextPredicate(ParseUtil::canParseInt); - this.addDrawableChild(this.repeatDelay); + this.repeatDelay.setValue(String.valueOf(soundBlock.repeatDelay)); + //FIXME 26.1 +// this.repeatDelay.setFilter(ParseUtil::canParseInt); + this.addRenderableWidget(this.repeatDelay); - this.distance = new TextFieldWidget( - this.client.textRenderer, + this.distance = new EditBox( + this.minecraft.font, width / 10 + (4 * width / 10) + 6, height / 2 + 40, (4 * width / 10) - 6, 20, - Text.empty()); + Component.empty()); this.distance.setMaxLength(16); - this.distance.setText(String.valueOf(soundBlock.distance)); - this.distance.setTextPredicate(ParseUtil::canParseDouble); - this.addDrawableChild(this.distance); + this.distance.setValue(String.valueOf(soundBlock.distance)); + //FIXME 26.1 +// this.distance.setFilter(ParseUtil::canParseDouble); + this.addRenderableWidget(this.distance); - this.relativeButton = new ButtonWidget.Builder(Text.stringifiedTranslatable("gui.glowcase.sound_positioning", soundBlock.relative), (action) -> { + this.relativeButton = new Button.Builder(Component.translatableEscape("gui.glowcase.sound_positioning", soundBlock.relative), (action) -> { soundBlock.relative = !soundBlock.relative; - this.relativeButton.setMessage(Text.stringifiedTranslatable("gui.glowcase.sound_positioning", soundBlock.relative)); - }).dimensions(width / 10, height / 2 + 90, (4 * width / 10) - 6, 20).build(); - this.addDrawableChild(this.relativeButton); + this.relativeButton.setMessage(Component.translatableEscape("gui.glowcase.sound_positioning", soundBlock.relative)); + }).bounds(width / 10, height / 2 + 90, (4 * width / 10) - 6, 20).build(); + this.addRenderableWidget(this.relativeButton); this.offset = new Vec3FieldsWidget( width / 10 + (4 * width / 10) + 6, height / 2 + 90, (4 * width / 10) - 6, 20, - this.client, + this.minecraft, soundBlock.offset); - this.addDrawableChild(this.offset); + this.addRenderableWidget(this.offset); - validSounds = Registries.SOUND_EVENT.stream() - .map(Registries.SOUND_EVENT::getId) + validSounds = BuiltInRegistries.SOUND_EVENT.stream() + .map(BuiltInRegistries.SOUND_EVENT::getKey) .filter(Objects::nonNull) .map(Identifier::toString) .collect(Collectors.toList()); - suggestionWidget = SuggestionListWidget.forTextFieldWithStaticSuggestions(soundId, client.textRenderer, validSounds, Function.identity(), this); + suggestionWidget = SuggestionListWidget.forTextFieldWithStaticSuggestions(soundId, minecraft.font, validSounds, Function.identity(), this); } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.sound_category_no_arg"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.sound_category_no_arg"), this.categoryButton.getX(), this.categoryButton.getY() - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.cancel_others"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.cancel_others"), this.cancelOthersButton.getX(), this.cancelOthersButton.getY() - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.volume"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.volume"), this.volume.getX(), this.volume.getY() - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.pitch"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.pitch"), this.pitch.getX(), this.pitch.getY() - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.repeat_delay"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.repeat_delay"), this.repeatDelay.getX(), this.repeatDelay.getY() - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.distance"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.distance"), this.distance.getX(), this.distance.getY() - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.sound_positioning_no_arg"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.sound_positioning_no_arg"), this.relativeButton.getX(), this.relativeButton.getY() - 20, 0xFFFFFFFF ); - context.drawTextWithShadow( - this.client.textRenderer, - Text.translatable("gui.glowcase.offset"), + context.drawString( + this.minecraft.font, + Component.translatable("gui.glowcase.offset"), this.offset.getX(), this.offset.getY() - 20, 0xFFFFFFFF ); @@ -195,24 +201,26 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double mouseX = event.x(); + double mouseY = event.y(); if (suggestionWidget.isMouseOver(mouseX, mouseY) && soundId.isFocused()) { - return suggestionWidget.mouseClicked(mouseX, mouseY, button); + return suggestionWidget.mouseClicked(event, doubleClick); } else { suggestionWidget.updateSuggestions(new ArrayList<>(), "", this); } - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(event, doubleClick); } @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) { if (suggestionWidget.draggingScrollbar) { - if (suggestionWidget.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) + if (suggestionWidget.mouseDragged(event, dx, dy)) return true; } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + return super.mouseDragged(event, dx, dy); } @Override @@ -226,31 +234,31 @@ public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmou } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (suggestionWidget.keyPressed(keyCode, scanCode, modifiers)) { + public boolean keyPressed(KeyEvent event) { + if (suggestionWidget.keyPressed(event)) { return true; } - return super.keyPressed(keyCode, scanCode, modifiers); + return super.keyPressed(event); } @Override - public void close() { - soundBlock.volume = (float) ParseUtil.parseOrDefault(this.volume.getText(), soundBlock.volume); - soundBlock.pitch = (float) ParseUtil.parseOrDefault(this.pitch.getText(), soundBlock.pitch); - soundBlock.repeatDelay = ParseUtil.parseOrDefault(this.repeatDelay.getText(), soundBlock.repeatDelay); + public void onClose() { + soundBlock.volume = (float) ParseUtil.parseOrDefault(this.volume.getValue(), soundBlock.volume); + soundBlock.pitch = (float) ParseUtil.parseOrDefault(this.pitch.getValue(), soundBlock.pitch); + soundBlock.repeatDelay = ParseUtil.parseOrDefault(this.repeatDelay.getValue(), soundBlock.repeatDelay); - soundBlock.distance = (float) ParseUtil.parseOrDefault(this.distance.getText(), soundBlock.distance); + soundBlock.distance = (float) ParseUtil.parseOrDefault(this.distance.getValue(), soundBlock.distance); soundBlock.offset = this.offset.value(); setSound(); - super.close(); + super.onClose(); } private void setSound() { - Objects.requireNonNull(this.client); + Objects.requireNonNull(this.minecraft); - String idText = this.soundId.getText(); + String idText = this.soundId.getValue(); Identifier id = Identifier.tryParse(idText); if (id != null) { diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SpriteBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SpriteBlockEditScreen.java index 4134779f..9fe21b85 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SpriteBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/SpriteBlockEditScreen.java @@ -6,17 +6,18 @@ import dev.hephaestus.glowcase.client.gui.widget.ingame.SuggestionListWidget; import dev.hephaestus.glowcase.packet.C2SEditSpriteBlock; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.registry.Registries; -import net.minecraft.resource.ResourceManager; -import net.minecraft.text.OrderedText; -import net.minecraft.text.Text; -import net.minecraft.text.TextColor; -import net.minecraft.util.Identifier; - +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextColor; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.FormattedCharSequence; import java.util.ArrayList; import java.util.List; import java.util.function.Function; @@ -24,14 +25,14 @@ public class SpriteBlockEditScreen extends GlowcaseScreen { private final SpriteBlockEntity spriteBlockEntity; - private TextFieldWidget spriteWidget; - private ButtonWidget spriteWidgetHelpButton; - private ButtonWidget rotationWidget; - private ButtonWidget zOffsetToggle; - private TextFieldWidget colorEntryWidget; - private TextFieldWidget scaleEntryWidget; + private EditBox spriteWidget; + private Button spriteWidgetHelpButton; + private Button rotationWidget; + private Button zOffsetToggle; + private EditBox colorEntryWidget; + private EditBox scaleEntryWidget; - private List spriteHelpTooltipText; + private List spriteHelpTooltipText; private SuggestionListWidget suggestionWidget; private List validSprites = new ArrayList<>(); @@ -44,63 +45,63 @@ public SpriteBlockEditScreen(SpriteBlockEntity spriteBlockEntity) { public void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; - this.spriteWidget = new GlowcaseTextFieldWidget(this.client.textRenderer, width / 2 - 90, height / 2 - 55, 180, 20, Text.empty()); + this.spriteWidget = new GlowcaseTextFieldWidget(this.minecraft.font, width / 2 - 90, height / 2 - 55, 180, 20, Component.empty()); this.spriteWidget.setMaxLength(255); - this.spriteWidget.setText(spriteBlockEntity.getSprite()); - this.spriteWidget.setChangedListener(string -> { - this.spriteBlockEntity.setSprite(this.spriteWidget.getText()); + this.spriteWidget.setValue(spriteBlockEntity.getSprite()); + this.spriteWidget.setResponder(string -> { + this.spriteBlockEntity.setSprite(this.spriteWidget.getValue()); }); - Tooltip spriteHelpTooltip = Tooltip.of(Text.translatable("gui.glowcase.screen.sprite_edit.sprite")); + Tooltip spriteHelpTooltip = Tooltip.create(Component.translatable("gui.glowcase.screen.sprite_edit.sprite")); - this.spriteWidgetHelpButton = ButtonWidget.builder(Text.literal("?"), action -> {}) - .dimensions(spriteWidget.getX() + spriteWidget.getWidth() + 4, spriteWidget.getY(), spriteWidget.getHeight(), spriteWidget.getHeight()) + this.spriteWidgetHelpButton = Button.builder(Component.literal("?"), action -> {}) + .bounds(spriteWidget.getX() + spriteWidget.getWidth() + 4, spriteWidget.getY(), spriteWidget.getHeight(), spriteWidget.getHeight()) .tooltip(spriteHelpTooltip) .build(); - this.rotationWidget = ButtonWidget.builder(Text.translatable("gui.glowcase.rotate"), (action) -> { + this.rotationWidget = Button.builder(Component.translatable("gui.glowcase.rotate"), (action) -> { this.spriteBlockEntity.rotation = (this.spriteBlockEntity.rotation + 45) % 360; - }).dimensions(width / 2 - 90, height / 2 - 25, 180, 20).build(); + }).bounds(width / 2 - 90, height / 2 - 25, 180, 20).build(); - this.zOffsetToggle = ButtonWidget.builder(Text.literal(this.spriteBlockEntity.zOffset.name()), action -> { + this.zOffsetToggle = Button.builder(Component.literal(this.spriteBlockEntity.zOffset.name()), action -> { switch (spriteBlockEntity.zOffset) { case FRONT -> spriteBlockEntity.zOffset = TextBlockEntity.ZOffset.CENTER; case CENTER -> spriteBlockEntity.zOffset = TextBlockEntity.ZOffset.BACK; case BACK -> spriteBlockEntity.zOffset = TextBlockEntity.ZOffset.FRONT; } - this.zOffsetToggle.setMessage(Text.literal(this.spriteBlockEntity.zOffset.name())); - }).dimensions(width / 2 - 90, height / 2 + 5, 180, 20).build(); + this.zOffsetToggle.setMessage(Component.literal(this.spriteBlockEntity.zOffset.name())); + }).bounds(width / 2 - 90, height / 2 + 5, 180, 20).build(); - this.colorEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 2 - 90, height / 2 + 35, 180, 20, Text.empty()); - this.colorEntryWidget.setText("#" + String.format("%1$06X", this.spriteBlockEntity.color & 0x00FFFFFF)); - this.colorEntryWidget.setChangedListener(string -> { - TextColor.parse(this.colorEntryWidget.getText()).ifSuccess(color -> { - this.spriteBlockEntity.color = color == null ? 0xFFFFFFFF : color.getRgb() | 0xFF000000; + this.colorEntryWidget = new EditBox(this.minecraft.font, width / 2 - 90, height / 2 + 35, 180, 20, Component.empty()); + this.colorEntryWidget.setValue("#" + String.format("%1$06X", this.spriteBlockEntity.color & 0x00FFFFFF)); + this.colorEntryWidget.setResponder(string -> { + TextColor.parseColor(this.colorEntryWidget.getValue()).ifSuccess(color -> { + this.spriteBlockEntity.color = color == null ? 0xFFFFFFFF : color.getValue() | 0xFF000000; }); }); - this.scaleEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 2 - 90, height / 2 + 65, 180, 20, Text.empty()); - this.scaleEntryWidget.setText(String.valueOf(this.spriteBlockEntity.scale)); - this.scaleEntryWidget.setChangedListener(string -> { + this.scaleEntryWidget = new EditBox(this.minecraft.font, width / 2 - 90, height / 2 + 65, 180, 20, Component.empty()); + this.scaleEntryWidget.setValue(String.valueOf(this.spriteBlockEntity.scale)); + this.scaleEntryWidget.setResponder(string -> { try { this.spriteBlockEntity.scale = Float.parseFloat(string); } catch (NumberFormatException ignored) {} }); - this.addDrawableChild(this.spriteWidget); - this.addDrawableChild(this.spriteWidgetHelpButton); - this.addDrawableChild(this.rotationWidget); - this.addDrawableChild(this.zOffsetToggle); - this.addDrawableChild(this.colorEntryWidget); - this.addDrawableChild(this.scaleEntryWidget); + this.addRenderableWidget(this.spriteWidget); + this.addRenderableWidget(this.spriteWidgetHelpButton); + this.addRenderableWidget(this.rotationWidget); + this.addRenderableWidget(this.zOffsetToggle); + this.addRenderableWidget(this.colorEntryWidget); + this.addRenderableWidget(this.scaleEntryWidget); - ResourceManager resourceManager = this.client.getResourceManager(); + ResourceManager resourceManager = this.minecraft.getResourceManager(); validSprites = allValidSprites(resourceManager); - suggestionWidget = SuggestionListWidget.forTextFieldWithStaticSuggestions(spriteWidget, client.textRenderer, validSprites, Function.identity(), this); + suggestionWidget = SuggestionListWidget.forTextFieldWithStaticSuggestions(spriteWidget, minecraft.font, validSprites, Function.identity(), this); } /** @@ -111,19 +112,19 @@ public static List allValidSprites(ResourceManager resourceManager) { // Add all sprites inside /textures/sprite, these are explicitly meant for the sprite block // and can be used with just their filename. As these are intended to be used here, we'll list them first - resourceManager.findResources("textures/sprite", id -> id.getPath().endsWith(".png")).forEach((sprite, res) -> { + resourceManager.listResources("textures/sprite", id -> id.getPath().endsWith(".png")).forEach((sprite, res) -> { validSprites.add(sprite.getPath().substring("textures/sprite/".length(), sprite.getPath().length() - 4)); }); // You can use any texture. Technically I think you can also use ones outside of texture // But findResources requires us to filter - resourceManager.findResources("textures", id -> id.getPath().endsWith(".png")).forEach((sprite, res) -> { + resourceManager.listResources("textures", id -> id.getPath().endsWith(".png")).forEach((sprite, res) -> { validSprites.add(sprite.toString()); }); // You can also display any item - Registries.ITEM.stream() - .map(Registries.ITEM::getId) + BuiltInRegistries.ITEM.stream() + .map(BuiltInRegistries.ITEM::getKey) .map(Identifier::toString) .forEach(validSprites::add); @@ -136,7 +137,7 @@ public static List allValidSprites(ResourceManager resourceManager) { } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); // Tooltip is handled this way, since setting the tooltip directly on the help button widget causes the tooltip // to clip off-screen at higher GUI scales. @@ -149,24 +150,26 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double mouseX = event.x(); + double mouseY = event.y(); if (suggestionWidget.isMouseOver(mouseX, mouseY) && spriteWidget.isFocused()) { - return suggestionWidget.mouseClicked(mouseX, mouseY, button); + return suggestionWidget.mouseClicked(event, doubleClick); } else { suggestionWidget.updateSuggestions(new ArrayList<>(), "", this); } - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(event, doubleClick); } @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) { if (suggestionWidget.draggingScrollbar) { - if (suggestionWidget.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) + if (suggestionWidget.mouseDragged(event, dx, dy)) return true; } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + return super.mouseDragged(event, dx, dy); } @Override @@ -180,18 +183,18 @@ public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmou } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (suggestionWidget.keyPressed(keyCode, scanCode, modifiers)) { + public boolean keyPressed(KeyEvent event) { + if (suggestionWidget.keyPressed(event)) { return true; } - return super.keyPressed(keyCode, scanCode, modifiers); + return super.keyPressed(event); } @Override - public void close() { - spriteBlockEntity.setSprite(spriteWidget.getText()); - spriteBlockEntity.markDirty(); + public void onClose() { + spriteBlockEntity.setSprite(spriteWidget.getValue()); + spriteBlockEntity.setChanged(); C2SEditSpriteBlock.of(spriteBlockEntity).send(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TabletEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TabletEditScreen.java index 86d77407..386b81d9 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TabletEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TabletEditScreen.java @@ -7,19 +7,19 @@ import dev.hephaestus.glowcase.client.ScreenImageCache.ScreenTexture; import dev.hephaestus.glowcase.packet.C2SEditTabletItem; import dev.hephaestus.glowcase.util.TextUtils; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.gui.widget.TextWidget; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.UUID; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.world.item.ItemStack; public class TabletEditScreen extends GlowcaseScreen { private static final Identifier TEXTURE = Glowcase.id("textures/gui/tablet.png"); @@ -55,16 +55,16 @@ public class TabletEditScreen extends GlowcaseScreen { private ScreenTexture next_slide; // Widgets - private TextWidget progressText; - private TextFieldWidget urlEntryWidget; - private TextFieldWidget altEntryWidget; - private ButtonWidget previousButton; - private ButtonWidget nextButton; + private StringWidget progressText; + private EditBox urlEntryWidget; + private EditBox altEntryWidget; + private Button previousButton; + private Button nextButton; public TabletEditScreen(ItemStack stack) { this.current = stack.getOrDefault(Glowcase.CURRENT_SLIDE_COMPONENT.get(), 0); - if (stack.contains(Glowcase.LINKED_SCREEN_COMPONENT.get())) + if (stack.has(Glowcase.LINKED_SCREEN_COMPONENT.get())) this.screen_pos = stack.get(Glowcase.LINKED_SCREEN_COMPONENT.get()); this.slides = new ArrayList<>(); @@ -74,72 +74,77 @@ public TabletEditScreen(ItemStack stack) { @Override protected void init() { super.init(); - if (this.client == null) return; + if (this.minecraft == null) return; - this.progressText = new TextWidget(width / 2 - BG_WIDTH / 2 + 5, height / 2 - BG_HEIGHT / 2 + 5, (int) (BG_WIDTH * .2), this.client.textRenderer.fontHeight, - Text.empty(), this.client.textRenderer) - .setTextColor(TXT_COLOR) - .alignLeft(); + this.progressText = new StringWidget(width / 2 - BG_WIDTH / 2 + 5, height / 2 - BG_HEIGHT / 2 + 5, (int) (BG_WIDTH * .2), this.minecraft.font.lineHeight, + Component.empty(), this.minecraft.font) +// FIXME these seem to no longer exist +// .color(TXT_COLOR) +// .alignLeft() + ; - Text linkedText = (screen_pos == null) ? Text.translatable("gui.glowcase.tablet.not_linked") - : Text.translatable("gui.glowcase.tablet.linked", screen_pos.getSecond().toShortString()); + Component linkedText = (screen_pos == null) ? Component.translatable("gui.glowcase.tablet.not_linked") + : Component.translatable("gui.glowcase.tablet.linked", screen_pos.getSecond().toShortString()); - TextWidget linkedTextWidget = new TextWidget(width / 2 - BG_WIDTH / 2 + 7 + (int) (BG_WIDTH * .2), height / 2 - BG_HEIGHT / 2 + 5, (int) (BG_WIDTH * .8) - 13, this.client.textRenderer.fontHeight, - linkedText, this.client.textRenderer) - .setTextColor(TXT_COLOR) - .alignRight(); + StringWidget linkedTextWidget = new StringWidget(width / 2 - BG_WIDTH / 2 + 7 + (int) (BG_WIDTH * .2), height / 2 - BG_HEIGHT / 2 + 5, (int) (BG_WIDTH * .8) - 13, this.minecraft.font.lineHeight, + linkedText, this.minecraft.font) - this.urlEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 2 - BG_WIDTH / 2 + 5, height / 2 + 30 - 1, BG_WIDTH - 10 - 55, 20, Text.empty()); +// FIXME these seem to no longer exist +// .setColor(TXT_COLOR) +// .alignRight() + ; + + this.urlEntryWidget = new EditBox(this.minecraft.font, width / 2 - BG_WIDTH / 2 + 5, height / 2 + 30 - 1, BG_WIDTH - 10 - 55, 20, Component.empty()); this.urlEntryWidget.setMaxLength(ScreenBlockEntity.URL_MAX_LENGTH); - this.urlEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.url")); - this.urlEntryWidget.setChangedListener((value) -> slide_dirty = true); + this.urlEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.url")); + this.urlEntryWidget.setResponder((value) -> slide_dirty = true); - this.altEntryWidget = new TextFieldWidget(this.client.textRenderer, width / 2 - BG_WIDTH / 2 + 5, height / 2 + 55 - 1, BG_WIDTH - 10, 20, Text.empty()); + this.altEntryWidget = new EditBox(this.minecraft.font, width / 2 - BG_WIDTH / 2 + 5, height / 2 + 55 - 1, BG_WIDTH - 10, 20, Component.empty()); this.altEntryWidget.setMaxLength(ScreenBlockEntity.ALT_MAX_LENGTH); - this.altEntryWidget.setPlaceholder(TextUtils.placeholder("gui.glowcase.alt")); - this.altEntryWidget.setChangedListener((value) -> slide_dirty = true); + this.altEntryWidget.setHint(TextUtils.placeholder("gui.glowcase.alt")); + this.altEntryWidget.setResponder((value) -> slide_dirty = true); - ButtonWidget updateButton = ButtonWidget.builder( - Text.translatable("gui.glowcase.refresh"), + Button updateButton = Button.builder( + Component.translatable("gui.glowcase.refresh"), action -> { syncSlide(); getSlides(); } - ).dimensions(width / 2 + BG_WIDTH / 2 - 55, height / 2 + 30 - 1, 50, 20).build(); + ).bounds(width / 2 + BG_WIDTH / 2 - 55, height / 2 + 30 - 1, 50, 20).build(); - previousButton = ButtonWidget.builder( - Text.translatable("gui.glowcase.previous"), + previousButton = Button.builder( + Component.translatable("gui.glowcase.previous"), action -> { syncSlide(); current--; getSlides(); } - ).dimensions(width / 2 - BG_WIDTH / 2 - 25 + SCREEN_X1, height / 2 - 25, 50, 20).build(); + ).bounds(width / 2 - BG_WIDTH / 2 - 25 + SCREEN_X1, height / 2 - 25, 50, 20).build(); - nextButton = ButtonWidget.builder( - Text.translatable("gui.glowcase.next"), + nextButton = Button.builder( + Component.translatable("gui.glowcase.next"), action -> { syncSlide(); current++; getSlides(); } - ).dimensions(width / 2 + BG_WIDTH / 2 - 35 + SCREEN_X1, height / 2 - 25, 50, 20).build(); + ).bounds(width / 2 + BG_WIDTH / 2 - 35 + SCREEN_X1, height / 2 - 25, 50, 20).build(); getSlides(); - this.addDrawableChild(this.progressText); - this.addDrawableChild(linkedTextWidget); - this.addDrawableChild(this.urlEntryWidget); - this.addDrawableChild(this.altEntryWidget); - this.addDrawableChild(updateButton); - this.addDrawableChild(previousButton); - this.addDrawableChild(nextButton); + this.addRenderableWidget(this.progressText); + this.addRenderableWidget(linkedTextWidget); + this.addRenderableWidget(this.urlEntryWidget); + this.addRenderableWidget(this.altEntryWidget); + this.addRenderableWidget(updateButton); + this.addRenderableWidget(previousButton); + this.addRenderableWidget(nextButton); } @Override - public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { + public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) { super.renderBackground(context, mouseX, mouseY, delta); - context.drawTexture(RenderPipelines.GUI_TEXTURED, TEXTURE, + context.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, width / 2 - BG_WIDTH / 2, height / 2 - BG_HEIGHT / 2, 0, 0, BG_WIDTH, BG_HEIGHT, BG_WIDTH, BG_WIDTH ); @@ -162,7 +167,7 @@ public void renderBackground(DrawContext context, int mouseX, int mouseY, float // We can't really use the build-in gradient because it only goes vertical // Left - context.drawTexture( + context.blit( RenderPipelines.GUI_TEXTURED, TEXTURE, width / 2 - BG_WIDTH / 2 + SCREEN_X1, height / 2 - BG_HEIGHT / 2 + SCREEN_Y1, @@ -172,7 +177,7 @@ public void renderBackground(DrawContext context, int mouseX, int mouseY, float ); // Right - context.drawTexture( + context.blit( RenderPipelines.GUI_TEXTURED, TEXTURE, width / 2 - BG_WIDTH / 2 + SCREEN_X2 - IMG_WIDTH + 1, height / 2 - BG_HEIGHT / 2 + SCREEN_Y1, @@ -193,7 +198,7 @@ public void renderBackground(DrawContext context, int mouseX, int mouseY, float * *

The screen texture will be rescaled to fit within the IMG_WIDTH and IMG_HEIGHT constants.

*/ - public void renderPicture(DrawContext context, @Nullable ScreenTexture slide, int x, int y, float scale) { + public void renderPicture(GuiGraphics context, @Nullable ScreenTexture slide, int x, int y, float scale) { if (slide == null || slide.getTexture().getSecond() == null) return; @@ -208,7 +213,7 @@ public void renderPicture(DrawContext context, @Nullable ScreenTexture slide, in int scaled_width = (int) (cur_width * final_scale); int scaled_height = (int) (cur_height * final_scale); - context.drawTexture( + context.blit( RenderPipelines.GUI_TEXTURED, slide.getTexture().getSecond(), x - scaled_width / 2, y - scaled_height / 2, 0, 0, scaled_width, scaled_height, scaled_width, scaled_height @@ -217,8 +222,8 @@ public void renderPicture(DrawContext context, @Nullable ScreenTexture slide, in public void syncSlide() { if (slide_dirty) { - slides.set(current, new Pair<>(this.urlEntryWidget.getText(), this.altEntryWidget.getText())); - C2SEditTabletItem.of(current, this.urlEntryWidget.getText(), this.altEntryWidget.getText()).send(); + slides.set(current, new Pair<>(this.urlEntryWidget.getValue(), this.altEntryWidget.getValue())); + C2SEditTabletItem.of(current, this.urlEntryWidget.getValue(), this.altEntryWidget.getValue()).send(); } } @@ -267,15 +272,15 @@ public void getSlides() { next_slide = null; // Update shown values - this.urlEntryWidget.setText(slide.getFirst()); - this.altEntryWidget.setText(slide.getSecond()); - this.progressText.setMessage(Text.translatable("gui.glowcase.progress", "" + (current + 1), slides.size())); + this.urlEntryWidget.setValue(slide.getFirst()); + this.altEntryWidget.setValue(slide.getSecond()); + this.progressText.setMessage(Component.translatable("gui.glowcase.progress", "" + (current + 1), slides.size())); slide_dirty = false; } @Override - public void close() { + public void onClose() { syncSlide(); - super.close(); + super.onClose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java index 2c1ee741..3abf7374 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java @@ -6,17 +6,20 @@ import dev.hephaestus.glowcase.client.util.ColorUtil; import dev.hephaestus.glowcase.packet.C2SEditTextBlock; import eu.pb4.placeholders.api.parsers.tag.TagRegistry; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.CheckboxWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.util.SelectionManager; -import net.minecraft.text.Text; -import net.minecraft.util.math.MathHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.Checkbox; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.font.TextFieldHelper; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.CharacterEvent; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.util.Mth; import org.lwjgl.glfw.GLFW; import java.awt.*; @@ -27,23 +30,23 @@ public class TextBlockEditScreen extends TextEditorScreen { private static final int innerPadding = 4; private final TextBlockEntity textBlockEntity; - private List textWidgets; + private List textWidgets; - private List colorListeners; + private List colorListeners; - private SelectionManager selectionManager; + private TextFieldHelper selectionManager; private int currentRow; private long ticksSinceOpened = 0; private ColorPickerWidget colorPickerWidget; - private ButtonWidget changeAlignment; - private TextFieldWidget colorEntryWidget; - private TextFieldWidget backgroundColorEntryWidget; + private Button changeAlignment; + private EditBox colorEntryWidget; + private EditBox backgroundColorEntryWidget; private Color colorEntryPreColorPicker; //used for color picker cancel button - private ButtonWidget zOffsetToggle; - private CheckboxWidget shadowToggle; + private Button zOffsetToggle; + private Checkbox shadowToggle; - private TextFieldWidget viewDistanceField; - private ButtonWidget viewDistanceHelpButton; + private EditBox viewDistanceField; + private Button viewDistanceHelpButton; public TextBlockEditScreen(TextBlockEntity textBlockEntity) { this.textBlockEntity = textBlockEntity; @@ -53,29 +56,29 @@ public TextBlockEditScreen(TextBlockEntity textBlockEntity) { public void init() { super.init(); - this.selectionManager = new SelectionManager( + this.selectionManager = new TextFieldHelper( () -> this.textBlockEntity.getRawLine(this.currentRow), (string) -> { textBlockEntity.setRawLine(this.currentRow, string); this.textBlockEntity.renderDirty = true; }, - SelectionManager.makeClipboardGetter(this.client), - SelectionManager.makeClipboardSetter(this.client), + TextFieldHelper.createClipboardGetter(this.minecraft), + TextFieldHelper.createClipboardSetter(this.minecraft), (string) -> true); int middle = width / 2; - ButtonWidget decreaseSize = ButtonWidget.builder(Text.literal("-"), action -> { - this.textBlockEntity.scale = Math.max(0, this.textBlockEntity.scale - (Screen.hasShiftDown() ? 1F : 0.125F)); + Button decreaseSize = Button.builder(Component.literal("-"), action -> { + this.textBlockEntity.scale = Math.max(0, this.textBlockEntity.scale - (/* FIXME store shift state somewhere Screen.hasShiftDown() ? 1F : */ 0.125F)); this.textBlockEntity.renderDirty = true; - }).dimensions(middle - 130, 0, 20, 20).build(); + }).bounds(middle - 130, 0, 20, 20).build(); - ButtonWidget increaseSize = ButtonWidget.builder(Text.literal("+"), action -> { - this.textBlockEntity.scale += Screen.hasShiftDown() ? 1F : 0.125F; + Button increaseSize = Button.builder(Component.literal("+"), action -> { + this.textBlockEntity.scale += /* FIXME store shift state somewhere Screen.hasShiftDown() ? 1F : */ 0.125F; this.textBlockEntity.renderDirty = true; - }).dimensions(middle - 110, 0, 20, 20).build(); + }).bounds(middle - 110, 0, 20, 20).build(); - this.changeAlignment = ButtonWidget.builder(Text.stringifiedTranslatable("gui.glowcase.alignment", this.textBlockEntity.textAlignment), action -> { + this.changeAlignment = Button.builder(Component.translatableEscape("gui.glowcase.alignment", this.textBlockEntity.textAlignment), action -> { switch (textBlockEntity.textAlignment) { case LEFT -> textBlockEntity.textAlignment = TextBlockEntity.TextAlignment.CENTER; case CENTER -> textBlockEntity.textAlignment = TextBlockEntity.TextAlignment.CENTER_LEFT; @@ -85,22 +88,22 @@ public void init() { } this.textBlockEntity.renderDirty = true; - this.changeAlignment.setMessage(Text.stringifiedTranslatable("gui.glowcase.alignment", this.textBlockEntity.textAlignment)); - }).dimensions(middle - 90 + innerPadding, 0, 160, 20).build(); + this.changeAlignment.setMessage(Component.translatableEscape("gui.glowcase.alignment", this.textBlockEntity.textAlignment)); + }).bounds(middle - 90 + innerPadding, 0, 160, 20).build(); - this.shadowToggle = CheckboxWidget.builder(Text.translatable("gui.glowcase.shadow"), this.textRenderer) - .checked(this.textBlockEntity.shadow) - .callback((widget, checked) -> { + this.shadowToggle = Checkbox.builder(Component.translatable("gui.glowcase.shadow"), this.font) + .selected(this.textBlockEntity.shadow) + .onValueChange((widget, checked) -> { this.textBlockEntity.shadow = checked; this.textBlockEntity.renderDirty = true; }) .pos(middle - 90 + innerPadding, 20 + innerPadding).build(); - this.colorEntryWidget = new TextFieldWidget(this.client.textRenderer, middle + 70 + innerPadding * 2, 0, 64, 20, Text.empty()); - this.colorEntryWidget.setTooltip(Tooltip.of(Text.translatable("gui.glowcase.color"))); - this.colorEntryWidget.setText(ColorUtil.toAlphaHex(this.textBlockEntity.color)); - this.colorEntryWidget.setChangedListener(string -> { - ColorUtil.parse(this.colorEntryWidget.getText(), this.textBlockEntity.color).ifSuccess(newColor -> { + this.colorEntryWidget = new EditBox(this.minecraft.font, middle + 70 + innerPadding * 2, 0, 64, 20, Component.empty()); + this.colorEntryWidget.setTooltip(Tooltip.create(Component.translatable("gui.glowcase.color"))); + this.colorEntryWidget.setValue(ColorUtil.toAlphaHex(this.textBlockEntity.color)); + this.colorEntryWidget.setResponder(string -> { + ColorUtil.parse(this.colorEntryWidget.getValue(), this.textBlockEntity.color).ifSuccess(newColor -> { final int color = (Math.max(newColor >>> 24, 0x1A) << 24) | (newColor & ColorUtil.COLOR_MASK); this.textBlockEntity.color = color; @@ -112,10 +115,10 @@ public void init() { }); }); - this.backgroundColorEntryWidget = new TextFieldWidget(this.client.textRenderer, middle + 136 + innerPadding * 2, 0, 64, 20, Text.empty()); - this.backgroundColorEntryWidget.setTooltip(Tooltip.of(Text.translatable("gui.glowcase.background_color"))); - this.backgroundColorEntryWidget.setText(ColorUtil.toAlphaHex(this.textBlockEntity.backgroundColor)); - this.backgroundColorEntryWidget.setChangedListener(string -> { + this.backgroundColorEntryWidget = new EditBox(this.minecraft.font, middle + 136 + innerPadding * 2, 0, 64, 20, Component.empty()); + this.backgroundColorEntryWidget.setTooltip(Tooltip.create(Component.translatable("gui.glowcase.background_color"))); + this.backgroundColorEntryWidget.setValue(ColorUtil.toAlphaHex(this.textBlockEntity.backgroundColor)); + this.backgroundColorEntryWidget.setResponder(string -> { ColorUtil.parse(string, this.textBlockEntity.backgroundColor).ifSuccess(newColor -> { this.textBlockEntity.backgroundColor = newColor; if (this.colorEntryWidget.isFocused()) { @@ -125,7 +128,7 @@ public void init() { }); }); - this.zOffsetToggle = ButtonWidget.builder(Text.literal(this.textBlockEntity.zOffset.name()), action -> { + this.zOffsetToggle = Button.builder(Component.literal(this.textBlockEntity.zOffset.name()), action -> { switch (textBlockEntity.zOffset) { case FRONT -> textBlockEntity.zOffset = TextBlockEntity.ZOffset.CENTER; case CENTER -> textBlockEntity.zOffset = TextBlockEntity.ZOffset.BACK; @@ -133,36 +136,36 @@ public void init() { } this.textBlockEntity.renderDirty = true; - this.zOffsetToggle.setMessage(Text.literal(this.textBlockEntity.zOffset.name())); - }).dimensions(middle + 2, 20 + innerPadding, 72, 20).build(); + this.zOffsetToggle.setMessage(Component.literal(this.textBlockEntity.zOffset.name())); + }).bounds(middle + 2, 20 + innerPadding, 72, 20).build(); this.colorPickerWidget = ColorPickerWidget.builder(this, 216, 10).size(182, 104).build(); this.colorPickerWidget.toggle(false); //start deactivated - this.viewDistanceField = new TextFieldWidget(this.client.textRenderer, middle - 203, 20 + innerPadding, 83 + innerPadding, 20, Text.empty()); - this.viewDistanceField.setText(String.valueOf(this.textBlockEntity.viewDistance)); - this.viewDistanceField.setChangedListener(s -> { + this.viewDistanceField = new EditBox(this.minecraft.font, middle - 203, 20 + innerPadding, 83 + innerPadding, 20, Component.empty()); + this.viewDistanceField.setValue(String.valueOf(this.textBlockEntity.viewDistance)); + this.viewDistanceField.setResponder(s -> { if (Floats.tryParse(s) instanceof Float parsed) { this.textBlockEntity.viewDistance = parsed; } }); - this.viewDistanceField.setTooltip(Tooltip.of(Text.translatable("gui.glowcase.screen.text_edit.view_distance"))); - this.viewDistanceHelpButton = ButtonWidget.builder(Text.literal("?"), action -> { + this.viewDistanceField.setTooltip(Tooltip.create(Component.translatable("gui.glowcase.screen.text_edit.view_distance"))); + this.viewDistanceHelpButton = Button.builder(Component.literal("?"), action -> { }) - .dimensions(middle - 115 + innerPadding + 5, 20 + innerPadding, 20, 20).build(); - this.viewDistanceHelpButton.setTooltip(Tooltip.of(Text.translatable("gui.glowcase.screen.text_edit.view_distance"))); + .bounds(middle - 115 + innerPadding + 5, 20 + innerPadding, 20, 20).build(); + this.viewDistanceHelpButton.setTooltip(Tooltip.create(Component.translatable("gui.glowcase.screen.text_edit.view_distance"))); - this.addDrawableChild(colorPickerWidget); - this.addDrawableChild(increaseSize); - this.addDrawableChild(decreaseSize); - this.addDrawableChild(this.changeAlignment); - this.addDrawableChild(this.shadowToggle); - this.addDrawableChild(this.zOffsetToggle); - this.addDrawableChild(this.colorEntryWidget); - this.addDrawableChild(this.backgroundColorEntryWidget); + this.addRenderableWidget(colorPickerWidget); + this.addRenderableWidget(increaseSize); + this.addRenderableWidget(decreaseSize); + this.addRenderableWidget(this.changeAlignment); + this.addRenderableWidget(this.shadowToggle); + this.addRenderableWidget(this.zOffsetToggle); + this.addRenderableWidget(this.colorEntryWidget); + this.addRenderableWidget(this.backgroundColorEntryWidget); - this.addDrawableChild(this.viewDistanceField); - this.addDrawableChild(this.viewDistanceHelpButton); + this.addRenderableWidget(this.viewDistanceField); + this.addRenderableWidget(this.viewDistanceHelpButton); this.textWidgets = List.of( this.colorEntryWidget, @@ -184,52 +187,55 @@ public void tick() { } @Override - public void close() { + public void onClose() { C2SEditTextBlock.of(textBlockEntity).send(); - super.close(); + super.onClose(); } private boolean isFocusedTextActive() { - final Element focused = this.getFocused(); - if (focused instanceof TextFieldWidget text) { - return text.isActive(); + final GuiEventListener focused = this.getFocused(); + if (focused instanceof EditBox text) { + return text.canConsumeInput(); } return false; } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (this.client != null) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { + if (this.minecraft != null) { super.render(context, mouseX, mouseY, delta); - context.getMatrices().pushMatrix(); - context.getMatrices().translate(0, 40 + 2 * this.width / 100F); + context.pose().pushMatrix(); + context.pose().translate(0, 40 + 2 * this.width / 100F); for (int i = 0; i < this.textBlockEntity.lines.size(); ++i) { - var text = this.currentRow == i ? Text.literal(this.textBlockEntity.getRawLine(i)) : this.textBlockEntity.lines.get(i); + var text = this.currentRow == i ? Component.literal(this.textBlockEntity.getRawLine(i)) : this.textBlockEntity.lines.get(i); - int lineWidth = this.textRenderer.getWidth(text); + int lineWidth = this.font.width(text); switch (this.textBlockEntity.textAlignment) { - case LEFT -> context.drawTextWithShadow(client.textRenderer, text, this.width / 10, i * 12, this.textBlockEntity.color); - case CENTER, CENTER_LEFT, CENTER_RIGHT -> context.drawTextWithShadow(client.textRenderer, text, this.width / 2 - lineWidth / 2, i * 12, this.textBlockEntity.color); - case RIGHT -> context.drawTextWithShadow(client.textRenderer, text, this.width - this.width / 10 - lineWidth, i * 12, this.textBlockEntity.color); + case LEFT -> + context.drawString(minecraft.font, text, this.width / 10, i * 12, this.textBlockEntity.color); + case CENTER, CENTER_LEFT, CENTER_RIGHT -> + context.drawString(minecraft.font, text, this.width / 2 - lineWidth / 2, i * 12, this.textBlockEntity.color); + case RIGHT -> + context.drawString(minecraft.font, text, this.width - this.width / 10 - lineWidth, i * 12, this.textBlockEntity.color); } } - int caretStart = this.selectionManager.getSelectionStart(); - int caretEnd = this.selectionManager.getSelectionEnd(); + int caretStart = this.selectionManager.getCursorPos(); + int caretEnd = this.selectionManager.getSelectionPos(); if (caretStart >= 0) { String line = this.textBlockEntity.getRawLine(this.currentRow); - int selectionStart = MathHelper.clamp(Math.min(caretStart, caretEnd), 0, line.length()); - int selectionEnd = MathHelper.clamp(Math.max(caretStart, caretEnd), 0, line.length()); + int selectionStart = Mth.clamp(Math.min(caretStart, caretEnd), 0, line.length()); + int selectionEnd = Mth.clamp(Math.max(caretStart, caretEnd), 0, line.length()); - String preSelection = line.substring(0, MathHelper.clamp(line.length(), 0, selectionStart)); - int startX = this.client.textRenderer.getWidth(preSelection); + String preSelection = line.substring(0, Mth.clamp(line.length(), 0, selectionStart)); + int startX = this.minecraft.font.width(preSelection); float push = switch (this.textBlockEntity.textAlignment) { case LEFT -> this.width / 10F; - case CENTER, CENTER_LEFT, CENTER_RIGHT -> this.width / 2F - this.textRenderer.getWidth(line) / 2F; - case RIGHT -> this.width - this.width / 10F - this.textRenderer.getWidth(line); + case CENTER, CENTER_LEFT, CENTER_RIGHT -> this.width / 2F - this.font.width(line) / 2F; + case RIGHT -> this.width - this.width / 10F - this.font.width(line); }; startX += (int) push; @@ -240,39 +246,40 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (selectionStart < line.length()) { context.fill(startX, caretStartY, startX + 1, caretStartY + 9, 0xCCFFFFFF); } else { - context.drawText(client.textRenderer, "_", startX, this.currentRow * 12, 0xFFFFFFFF, false); + context.drawString(minecraft.font, "_", startX, this.currentRow * 12, 0xFFFFFFFF, false); } } if (caretStart != caretEnd) { - int endX = startX + this.client.textRenderer.getWidth(line.substring(selectionStart, selectionEnd)); - context.drawSelection(startX, caretStartY, endX, caretStartY + 9); + int endX = startX + this.minecraft.font.width(line.substring(selectionStart, selectionEnd)); + context.textHighlight(startX, caretStartY, endX, caretStartY + 9, false); } } - context.getMatrices().popMatrix(); - context.drawTextWithShadow(client.textRenderer, Text.translatable("gui.glowcase.scale_value", this.textBlockEntity.scale), width / 2 - 203, 7, 0xFFFFFFFF); + context.pose().popMatrix(); + context.drawString(minecraft.font, Component.translatable("gui.glowcase.scale_value", this.textBlockEntity.scale), width / 2 - 203, 7, 0xFFFFFFFF); colorPickerWidget.render(context, mouseX, mouseY, delta); } } @Override - public boolean charTyped(char chr, int keyCode) { + public boolean charTyped(CharacterEvent event) { for (final var element : this.textWidgets) { - if (element.charTyped(chr, keyCode)) { + if (element.charTyped(event)) { return true; } } - return this.selectionManager.insert(chr); + return this.selectionManager.charTyped(event); } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + public boolean keyPressed(KeyEvent event) { + var keyCode = event.key(); if (keyCode != GLFW.GLFW_KEY_ESCAPE) { for (final var element : this.textWidgets) { if (element.isFocused()) { - return element.keyPressed(keyCode, scanCode, modifiers); + return element.keyPressed(event); } } } @@ -293,35 +300,35 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { this.textBlockEntity.addRawLine(this.currentRow + 1, this.textBlockEntity.getRawLine(this.currentRow).substring( - MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.textBlockEntity.getRawLine(this.currentRow).length()) + Mth.clamp(this.selectionManager.getCursorPos(), 0, this.textBlockEntity.getRawLine(this.currentRow).length()) )); this.textBlockEntity.setRawLine(this.currentRow, - this.textBlockEntity.getRawLine(this.currentRow).substring(0, MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.textBlockEntity.getRawLine(this.currentRow).length()) + this.textBlockEntity.getRawLine(this.currentRow).substring(0, Mth.clamp(this.selectionManager.getCursorPos(), 0, this.textBlockEntity.getRawLine(this.currentRow).length()) )); this.textBlockEntity.renderDirty = true; ++this.currentRow; - this.selectionManager.moveCursorToStart(); + this.selectionManager.setCursorToStart(); return true; } else if (keyCode == GLFW.GLFW_KEY_UP) { this.currentRow = Math.max(this.currentRow - 1, 0); - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); return true; } else if (keyCode == GLFW.GLFW_KEY_DOWN) { this.currentRow = Math.min(this.currentRow + 1, (this.textBlockEntity.lines.size() - 1)); - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); return true; - } else if (keyCode == GLFW.GLFW_KEY_BACKSPACE && this.currentRow > 0 && this.textBlockEntity.lines.size() > 1 && this.selectionManager.getSelectionStart() == 0 && this.selectionManager.getSelectionEnd() == this.selectionManager.getSelectionStart()) { + } else if (keyCode == GLFW.GLFW_KEY_BACKSPACE && this.currentRow > 0 && this.textBlockEntity.lines.size() > 1 && this.selectionManager.getCursorPos() == 0 && this.selectionManager.getSelectionPos() == this.selectionManager.getCursorPos()) { --this.currentRow; - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); deleteLine(); return true; - } else if (keyCode == GLFW.GLFW_KEY_DELETE && this.currentRow < this.textBlockEntity.lines.size() - 1 && this.selectionManager.getSelectionEnd() == this.textBlockEntity.getRawLine(this.currentRow).length()) { + } else if (keyCode == GLFW.GLFW_KEY_DELETE && this.currentRow < this.textBlockEntity.lines.size() - 1 && this.selectionManager.getSelectionPos() == this.textBlockEntity.getRawLine(this.currentRow).length()) { deleteLine(); return true; } else { //formatting hotkeys - if (Screen.hasControlDown()) { + if (event.hasControlDown()) { if (keyCode == GLFW.GLFW_KEY_B) { insertTag(TagRegistry.SAFE.getTag("bold"), true); return true; @@ -344,8 +351,8 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { } try { - boolean val = this.selectionManager.handleSpecialKey(keyCode) || super.keyPressed(keyCode, scanCode, modifiers); - int selectionOffset = this.textBlockEntity.getRawLine(this.currentRow).length() - this.selectionManager.getSelectionStart(); + boolean val = this.selectionManager.keyPressed(event) || super.keyPressed(event); + int selectionOffset = this.textBlockEntity.getRawLine(this.currentRow).length() - this.selectionManager.getCursorPos(); // Find line feed characters and create proper newlines for (int i = 0; i < this.textBlockEntity.lines.size(); ++i) { @@ -354,21 +361,21 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (lineFeedIndex >= 0) { this.textBlockEntity.addRawLine(i + 1, this.textBlockEntity.getRawLine(i).substring( - MathHelper.clamp(lineFeedIndex + 1, 0, this.textBlockEntity.getRawLine(i).length()) + Mth.clamp(lineFeedIndex + 1, 0, this.textBlockEntity.getRawLine(i).length()) )); this.textBlockEntity.setRawLine(i, - this.textBlockEntity.getRawLine(i).substring(0, MathHelper.clamp(lineFeedIndex, 0, this.textBlockEntity.getRawLine(i).length()) + this.textBlockEntity.getRawLine(i).substring(0, Mth.clamp(lineFeedIndex, 0, this.textBlockEntity.getRawLine(i).length()) )); this.textBlockEntity.renderDirty = true; ++this.currentRow; - this.selectionManager.putCursorAtEnd(); - this.selectionManager.moveCursor(-selectionOffset); + this.selectionManager.setCursorToEnd(); + this.selectionManager.moveByChars(-selectionOffset); } } return val; } catch (StringIndexOutOfBoundsException e) { e.printStackTrace(); - MinecraftClient.getInstance().setScreen(null); + Minecraft.getInstance().setScreen(null); return false; } } @@ -384,7 +391,7 @@ private void deleteLine() { this.textBlockEntity.renderDirty = true; } - private void colorListenerClicked(TextFieldWidget textWidget) { + private void colorListenerClicked(EditBox textWidget) { this.colorPickerWidget.setPosition(Math.min(textWidget.getX(), width - colorPickerWidget.getWidth()), textWidget.getY() + textWidget.getHeight()); this.colorPickerWidget.setTargetElement(textWidget); this.colorPickerWidget.setOnAccept(null); @@ -393,12 +400,12 @@ private void colorListenerClicked(TextFieldWidget textWidget) { }); this.colorPickerWidget.setChangeListener(color -> { final int newColor = ColorUtil.transferAlpha(this.colorEntryPreColorPicker.getRGB(), color.getRGB()); - textWidget.setText(ColorUtil.toAlphaHex(newColor)); + textWidget.setValue(ColorUtil.toAlphaHex(newColor)); }); this.colorPickerWidget.setPresetListener((color, formatting) -> { this.colorPickerWidget.setColor(color); }); - ColorUtil.parse(textWidget.getText(), ColorUtil.WHITE).ifSuccess(color -> { + ColorUtil.parse(textWidget.getValue(), ColorUtil.WHITE).ifSuccess(color -> { final Color pickerColor = new Color(color); this.colorEntryPreColorPicker = pickerColor; this.colorPickerWidget.setColor(pickerColor); @@ -407,11 +414,13 @@ private void colorListenerClicked(TextFieldWidget textWidget) { } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + double mouseX = event.x(); + double mouseY = event.y(); int topOffset = (int) (40 + 2 * this.width / 100F); for (final var text : textWidgets) { - if (!text.mouseClicked(mouseX, mouseY, button)) { + if (!text.mouseClicked(event, doubleClick)) { continue; } this.setFocused(text); @@ -426,7 +435,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { if (colorPickerWidget.active && colorPickerWidget.visible) { if (colorPickerWidget.isMouseOver(mouseX, mouseY)) { - colorPickerWidget.mouseClicked(mouseX, mouseY, button); + colorPickerWidget.mouseClicked(event, doubleClick); this.setFocused(colorPickerWidget); this.setDragging(true); return true; @@ -437,10 +446,10 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } } if (mouseY > topOffset) { - this.currentRow = MathHelper.clamp((int) (mouseY - topOffset) / 12, 0, this.textBlockEntity.lines.size() - 1); + this.currentRow = Mth.clamp((int) (mouseY - topOffset) / 12, 0, this.textBlockEntity.lines.size() - 1); this.setFocused(null); String baseContents = this.textBlockEntity.getRawLine(currentRow); - int baseContentsWidth = this.textRenderer.getWidth(baseContents); + int baseContentsWidth = this.font.width(baseContents); int contentsStart; int contentsEnd; switch (this.textBlockEntity.textAlignment) { @@ -464,20 +473,20 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } if (mouseX <= contentsStart) { - this.selectionManager.moveCursorToStart(); + this.selectionManager.setCursorToStart(); } else if (mouseX >= contentsEnd) { - this.selectionManager.putCursorAtEnd(); + this.selectionManager.setCursorToEnd(); } else { int lastWidth = 0; for (int i = 1; i < baseContents.length(); i++) { String testContents = baseContents.substring(0, i); - int width = this.textRenderer.getWidth(testContents); + int width = this.font.width(testContents); int midpointWidth = (width + lastWidth) / 2; if (mouseX < contentsStart + midpointWidth) { - this.selectionManager.moveCursorTo(i - 1, false); + this.selectionManager.setCursorPos(i - 1, false); break; } else if (mouseX <= contentsStart + width) { - this.selectionManager.moveCursorTo(i, false); + this.selectionManager.setCursorPos(i, false); break; } lastWidth = width; @@ -485,7 +494,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } return true; } else { - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(event, doubleClick); } } @@ -500,7 +509,7 @@ public void toggleColorPicker(boolean active) { } @Override - SelectionManager getSelectionManager() { + TextFieldHelper getSelectionManager() { return this.selectionManager; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextEditorScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextEditorScreen.java index 9c8ff6c8..0fe086ae 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextEditorScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextEditorScreen.java @@ -4,57 +4,52 @@ import dev.hephaestus.glowcase.client.gui.widget.ingame.ColorPickerWidget; import eu.pb4.placeholders.api.parsers.tag.TagRegistry; import eu.pb4.placeholders.api.parsers.tag.TextTag; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.SimpleGuiElementRenderState; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.client.util.SelectionManager; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import org.jetbrains.annotations.Nullable; import org.joml.Vector2i; import java.util.Arrays; import java.util.Comparator; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.font.TextFieldHelper; +import net.minecraft.network.chat.Component; public abstract class TextEditorScreen extends GlowcaseScreen implements ColorPickerIncludedScreen { - private ButtonWidget colorText; - private ButtonWidget[] widgets = new ButtonWidget[0]; + private Button colorText; + private Button[] widgets = new Button[0]; - abstract SelectionManager getSelectionManager(); + abstract TextFieldHelper getSelectionManager(); protected void addFormattingButtons(int x, int y, int innerPadding, int buttonSize, int buttonPadding) { int buttonX = x + innerPadding * 2; //adding numbers to this variable because I personally find that more readable, that's all int buttonY = y + innerPadding; //reduce the times this is calculated - ButtonWidget boldText = ButtonWidget.builder(Text.literal("B").formatted(Formatting.BOLD), action -> { + Button boldText = Button.builder(Component.literal("B").withStyle(ChatFormatting.BOLD), action -> { insertTag(TagRegistry.SAFE.getTag("bold"), true); - }).dimensions(buttonX, buttonY, buttonSize, buttonSize).build(); + }).bounds(buttonX, buttonY, buttonSize, buttonSize).build(); buttonX += buttonSize + buttonPadding; - ButtonWidget italicizeText = ButtonWidget.builder(Text.literal("I").formatted(Formatting.ITALIC), action -> { + Button italicizeText = Button.builder(Component.literal("I").withStyle(ChatFormatting.ITALIC), action -> { insertTag(TagRegistry.SAFE.getTag("italic"), true); - }).dimensions(buttonX, buttonY, buttonSize, buttonSize).build(); + }).bounds(buttonX, buttonY, buttonSize, buttonSize).build(); buttonX += buttonSize + buttonPadding; - ButtonWidget strikeText = ButtonWidget.builder(Text.literal("S").formatted(Formatting.STRIKETHROUGH), action -> { + Button strikeText = Button.builder(Component.literal("S").withStyle(ChatFormatting.STRIKETHROUGH), action -> { insertTag(TagRegistry.SAFE.getTag("strikethrough"), true); - }).dimensions(buttonX, buttonY, buttonSize, buttonSize).build(); + }).bounds(buttonX, buttonY, buttonSize, buttonSize).build(); buttonX += buttonSize + buttonPadding; - ButtonWidget underlineText = ButtonWidget.builder(Text.literal("U").formatted(Formatting.UNDERLINE), action -> { + Button underlineText = Button.builder(Component.literal("U").withStyle(ChatFormatting.UNDERLINE), action -> { insertTag(TagRegistry.SAFE.getTag("underline"), true); - }).dimensions(buttonX, buttonY, buttonSize, buttonSize).build(); + }).bounds(buttonX, buttonY, buttonSize, buttonSize).build(); buttonX += buttonSize + buttonPadding; //not using the actual obfuscated formatting here because the movement can be annoying - ButtonWidget obfuscateText = ButtonWidget.builder(Text.literal("@"), action -> { + Button obfuscateText = Button.builder(Component.literal("@"), action -> { insertTag(TagRegistry.SAFE.getTag("obfuscated"), true); - }).dimensions(buttonX, buttonY, buttonSize, buttonSize).build(); + }).bounds(buttonX, buttonY, buttonSize, buttonSize).build(); buttonX += buttonSize + buttonPadding; // + 4? (only works on padding of 2) - this.colorText = ButtonWidget.builder(Text.literal("\uD83D\uDD8C"), action -> { + this.colorText = Button.builder(Component.literal("\uD83D\uDD8C"), action -> { ColorPickerWidget colorPickerWidget = colorPickerWidget(); colorPickerWidget.setPosition(216, 10); colorPickerWidget.setTargetElement(this.colorText); @@ -73,22 +68,22 @@ protected void addFormattingButtons(int x, int y, int innerPadding, int buttonSi }); colorPickerWidget.setChangeListener(null); toggleColorPicker(!colorPickerWidget.active); - }).dimensions(buttonX, buttonY, buttonSize, buttonSize).build(); + }).bounds(buttonX, buttonY, buttonSize, buttonSize).build(); - widgets = new ButtonWidget[]{ + widgets = new Button[]{ boldText, italicizeText, strikeText, underlineText, obfuscateText, colorText }; - this.addDrawableChild(boldText); - this.addDrawableChild(italicizeText); - this.addDrawableChild(strikeText); - this.addDrawableChild(underlineText); - this.addDrawableChild(obfuscateText); - this.addDrawableChild(colorText); + this.addRenderableWidget(boldText); + this.addRenderableWidget(italicizeText); + this.addRenderableWidget(strikeText); + this.addRenderableWidget(underlineText); + this.addRenderableWidget(obfuscateText); + this.addRenderableWidget(colorText); } public void toggleWidgets(boolean active) { - for (ButtonWidget widget : widgets) + for (Button widget : widgets) widget.active = active; } @@ -101,47 +96,47 @@ public void insertTag(TextTag tag, boolean findShortest) { name = Arrays.stream(tag.aliases()).min(Comparator.comparing(String::length)).get(); } - SelectionManager selectionManager = getSelectionManager(); + TextFieldHelper selectionManager = getSelectionManager(); - int selectedStart = selectionManager.getSelectionStart(); - int selectedEnd = selectionManager.getSelectionEnd(); + int selectedStart = selectionManager.getCursorPos(); + int selectedEnd = selectionManager.getSelectionPos(); if(selectedStart != selectedEnd) { int selectedAmount = Math.abs(selectedEnd - selectedStart); //text is selected/highlighted - selection is determined based on the direction it happens, so an extra check is needed - selectionManager.moveCursor(selectedStart < selectedEnd ? 0 : -selectedAmount, false, SelectionManager.SelectionType.CHARACTER); - selectionManager.insert("<" + name + ">"); - selectionManager.moveCursor(selectedAmount, false, SelectionManager.SelectionType.CHARACTER); - selectionManager.insert(""); - selectionManager.moveCursor(-name.length() - 3, false, SelectionManager.SelectionType.CHARACTER); - selectionManager.setSelection(selectedStart + name.length() + 2, selectedEnd + name.length() + 2); + selectionManager.moveBy(selectedStart < selectedEnd ? 0 : -selectedAmount, false, TextFieldHelper.CursorStep.CHARACTER); + selectionManager.insertText("<" + name + ">"); + selectionManager.moveBy(selectedAmount, false, TextFieldHelper.CursorStep.CHARACTER); + selectionManager.insertText(""); + selectionManager.moveBy(-name.length() - 3, false, TextFieldHelper.CursorStep.CHARACTER); + selectionManager.setSelectionRange(selectedStart + name.length() + 2, selectedEnd + name.length() + 2); } else { - selectionManager.insert("<" + name + ">"); - selectionManager.moveCursor(-name.length() - 3, false, SelectionManager.SelectionType.CHARACTER); + selectionManager.insertText("<" + name + ">"); + selectionManager.moveBy(-name.length() - 3, false, TextFieldHelper.CursorStep.CHARACTER); } } @Override public void insertHexTag(String hex) { - SelectionManager selectionManager = getSelectionManager(); - int selectedStart = selectionManager.getSelectionStart(); - int selectedEnd = selectionManager.getSelectionEnd(); + TextFieldHelper selectionManager = getSelectionManager(); + int selectedStart = selectionManager.getCursorPos(); + int selectedEnd = selectionManager.getSelectionPos(); if(selectedStart != selectedEnd) { int selectedAmount = Math.abs(selectedEnd - selectedStart); //text is selected/highlighted - selection is determined based on the direction it happens, so an extra check is needed - selectionManager.moveCursor(selectedStart < selectedEnd ? 0 : -selectedAmount, false, SelectionManager.SelectionType.CHARACTER); - selectionManager.insert("<" + hex + ">"); - selectionManager.moveCursor(selectedAmount, false, SelectionManager.SelectionType.CHARACTER); - selectionManager.insert(""); - selectionManager.moveCursor(-hex.length() - 3, false, SelectionManager.SelectionType.CHARACTER); - selectionManager.setSelection(selectedStart + hex.length() + 2, selectedEnd + hex.length() + 2); + selectionManager.moveBy(selectedStart < selectedEnd ? 0 : -selectedAmount, false, TextFieldHelper.CursorStep.CHARACTER); + selectionManager.insertText("<" + hex + ">"); + selectionManager.moveBy(selectedAmount, false, TextFieldHelper.CursorStep.CHARACTER); + selectionManager.insertText(""); + selectionManager.moveBy(-hex.length() - 3, false, TextFieldHelper.CursorStep.CHARACTER); + selectionManager.setSelectionRange(selectedStart + hex.length() + 2, selectedEnd + hex.length() + 2); } else { - selectionManager.insert("<" + hex + ">"); - selectionManager.moveCursor(-hex.length() - 3, false, SelectionManager.SelectionType.CHARACTER); + selectionManager.insertText("<" + hex + ">"); + selectionManager.moveBy(-hex.length() - 3, false, TextFieldHelper.CursorStep.CHARACTER); } } @Override - public void insertFormattingTag(Formatting formatting) { + public void insertFormattingTag(ChatFormatting formatting) { insertTag(TagRegistry.SAFE.getTag(formatting.getName()), false); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPickerWidget.java b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPickerWidget.java index a01b75f1..4bec074c 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPickerWidget.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPickerWidget.java @@ -1,21 +1,23 @@ package dev.hephaestus.glowcase.client.gui.widget.ingame; import com.mojang.blaze3d.pipeline.RenderPipeline; +import com.mojang.blaze3d.vertex.VertexConsumer; import dev.hephaestus.glowcase.client.gui.screen.ingame.ColorPickerIncludedScreen; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.SimpleGuiElementRenderState; -import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; -import net.minecraft.client.gui.widget.PressableWidget; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.gui.navigation.ScreenRectangle; +import net.minecraft.client.gui.render.TextureSetup; +import net.minecraft.client.gui.render.state.GuiElementRenderState; +import net.minecraft.client.input.InputWithModifiers; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; import org.apache.commons.compress.utils.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,14 +31,14 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; -public class ColorPickerWidget extends PressableWidget { - static final Identifier CONFIRM_TEXTURE = Identifier.ofVanilla("pending_invite/accept"); - static final Identifier CONFIRM_HIGHLIGHTED_TEXTURE = Identifier.ofVanilla("pending_invite/accept_highlighted"); - static final Identifier CANCEL_TEXTURE = Identifier.ofVanilla("pending_invite/reject"); - static final Identifier CANCEL_HIGHLIGHTED_TEXTURE = Identifier.ofVanilla("pending_invite/reject_highlighted"); +public class ColorPickerWidget extends AbstractButton { + static final Identifier CONFIRM_TEXTURE = Identifier.withDefaultNamespace("pending_invite/accept"); + static final Identifier CONFIRM_HIGHLIGHTED_TEXTURE = Identifier.withDefaultNamespace("pending_invite/accept_highlighted"); + static final Identifier CANCEL_TEXTURE = Identifier.withDefaultNamespace("pending_invite/reject"); + static final Identifier CANCEL_HIGHLIGHTED_TEXTURE = Identifier.withDefaultNamespace("pending_invite/reject_highlighted"); public final ColorPickerIncludedScreen screen; - public Element targetElement; + public GuiEventListener targetElement; public Color color = Color.red; public boolean includePresets = true; public ArrayList presetWidgets = Lists.newArrayList(); @@ -44,7 +46,7 @@ public class ColorPickerWidget extends PressableWidget { public IconButtonWidget confirmButton; public IconButtonWidget cancelButton; private Consumer changeListener; - private BiConsumer presetListener; + private BiConsumer presetListener; private Consumer onAccept; private Consumer onCancel; @@ -68,7 +70,7 @@ public static ColorPickerWidget.Builder builder(ColorPickerIncludedScreen screen return new ColorPickerWidget.Builder(screen, x, y); } - public ColorPickerWidget(ColorPickerIncludedScreen screen, int x, int y, int width, int height, Text message) { + public ColorPickerWidget(ColorPickerIncludedScreen screen, int x, int y, int width, int height, Component message) { super(x, y, width, height, message); this.screen = screen; @@ -83,7 +85,7 @@ public ColorPickerWidget(ColorPickerIncludedScreen screen, int x, int y, int wid updateThumbPositions(); } - public void setTargetElement(Element element) { + public void setTargetElement(GuiEventListener element) { this.targetElement = element; } @@ -133,7 +135,7 @@ public void insertColor(Color color) { this.screen.insertHexTag(hex); } - public void insertFormatting(Formatting formatting) { + public void insertFormatting(ChatFormatting formatting) { this.screen.insertFormattingTag(formatting); } @@ -144,17 +146,17 @@ public void setColor(Color color) { } @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + protected void renderContents(GuiGraphics context, int mouseX, int mouseY, float delta) { if (!visible) return; updateHSL(); //context.setShaderColor(1f, 1f, 1f, this.alpha); /*RenderSystem.enableBlend(); RenderSystem.enableDepthTest();*/ - Matrix3x2fStack matrices = context.getMatrices(); + Matrix3x2fStack matrices = context.pose(); //context.applyBlur(); - context.createNewRootLayer(); + context.nextStratum(); matrices.pushMatrix(); int x = this.getX(); @@ -164,8 +166,8 @@ protected void renderWidget(DrawContext context, int mouseX, int mouseY, float d int height = this.getHeight(); //background - context.drawTexture(RenderPipelines.GUI_TEXTURED, Identifier.ofVanilla("textures/gui/inworld_menu_list_background.png"), x, y, 0, 0, width, height, 32, 32); - if (this.isSelected()) { + context.blit(RenderPipelines.GUI_TEXTURED, Identifier.withDefaultNamespace("textures/gui/inworld_menu_list_background.png"), x, y, 0, 0, width, height, 32, 32); + if (this.isHoveredOrFocused()) { //outline drawOutline(context, x, y, width, height, Color.white); } @@ -184,8 +186,8 @@ protected void renderWidget(DrawContext context, int mouseX, int mouseY, float d drawPresets(context, mouseX, mouseY, delta, previewX, presetY, y + height - presetY, z + 1, presetSize, width / (presetSize + presetPadding), presetPadding); } - this.confirmButton.renderWidget(context, mouseX, mouseY, delta); - this.cancelButton.renderWidget(context, mouseX, mouseY, delta); + this.confirmButton.render(context, mouseX, mouseY, delta); + this.cancelButton.render(context, mouseX, mouseY, delta); matrices.popMatrix(); @@ -218,11 +220,11 @@ public void updatePositions() { presetY = hueY + hueHeight + presetPadding; } - private void drawColorPreview(DrawContext context, int x, int y, int width, int height) { + private void drawColorPreview(GuiGraphics context, int x, int y, int width, int height) { context.fill(x, y, x + width, y + height, this.color.getRGB()); } - private void drawHueBar(DrawContext context, int x, int y, int width, int height, int z) { + private void drawHueBar(GuiGraphics context, int x, int y, int width, int height, int z) { //rainbow gradient int[] colors = new int[]{ Color.red.getRGB(), Color.yellow.getRGB(), Color.green.getRGB(), @@ -245,7 +247,7 @@ private void drawHueBar(DrawContext context, int x, int y, int width, int height drawOutline(context, hueThumbX - 3, y - 1, 6, height + 2, Color.white); } - private void drawSatLight(DrawContext context, int x, int y, int width, int height) { + private void drawSatLight(GuiGraphics context, int x, int y, int width, int height) { //white to current color's hue, left to right sidewaysGradient(context, x, y, width, height, Color.white.getRGB(), getRgbFromHueThumb()); @@ -257,7 +259,7 @@ private void drawSatLight(DrawContext context, int x, int y, int width, int heig drawOutline(context, satLightThumbX - 4, satLightThumbY - 4, 8, 8, Color.white); } - private void drawOutline(DrawContext context, int x, int y, int width, int height, Color outlineColor) { + private void drawOutline(GuiGraphics context, int x, int y, int width, int height, Color outlineColor) { int color = outlineColor.getRGB(); context.fill(x, y, x + width, y + 1, color); context.fill(x, y, x + 1, y + height, color); @@ -265,21 +267,21 @@ private void drawOutline(DrawContext context, int x, int y, int width, int heigh context.fill(x, y + height, x + width, y + height - 1, color); } - private void sidewaysGradient(DrawContext context, int x, int y, int width, int height, int startColor, int endColor) { - context.state.addSimpleElement(new SimpleGuiElementRenderState() { + private void sidewaysGradient(GuiGraphics context, int x, int y, int width, int height, int startColor, int endColor) { + context.guiRenderState.submitGuiElement(new GuiElementRenderState() { @Override - public ScreenRect bounds() { - return new ScreenRect(x, y, width, height).transformEachVertex(context.getMatrices()); + public ScreenRectangle bounds() { + return new ScreenRectangle(x, y, width, height).transformMaxBounds(context.pose()); } @Override - public void setupVertices(VertexConsumer vertices, float depth) { - Matrix3x2fStack matrix = context.getMatrices(); - vertices.vertex(matrix, x, y, depth).color(startColor); - vertices.vertex(matrix, x, y + height, depth).color(startColor); - vertices.vertex(matrix, x + width, y + height, depth).color(endColor); - vertices.vertex(matrix, x + width, y, depth).color(endColor); + public void buildVertices(VertexConsumer vertices) { + Matrix3x2fStack matrix = context.pose(); + vertices.addVertexWith2DPose(matrix, x, y).setColor(startColor); + vertices.addVertexWith2DPose(matrix, x, y + height).setColor(startColor); + vertices.addVertexWith2DPose(matrix, x + width, y + height).setColor(endColor); + vertices.addVertexWith2DPose(matrix, x + width, y).setColor(endColor); } @Override @@ -289,23 +291,23 @@ public RenderPipeline pipeline() { @Override public TextureSetup textureSetup() { - return TextureSetup.empty(); + return TextureSetup.noTexture(); } @Override - public @Nullable ScreenRect scissorArea() { + public @Nullable ScreenRectangle scissorArea() { return null; } }); } - private void drawPresets(DrawContext context, int mouseX, int mouseY, float delta, int x, int y, int height, int z, int presetSize, int presetsPerLine, int presetPadding) { + private void drawPresets(GuiGraphics context, int mouseX, int mouseY, float delta, int x, int y, int height, int z, int presetSize, int presetsPerLine, int presetPadding) { int presetX = x; int presetY = y; int renderedPresets = 0; for (ColorPresetWidget preset : this.presetWidgets) { preset.setPosition(presetX, presetY, z, presetSize); - preset.renderWidget(context, mouseX, mouseY, delta); + preset.render(context, mouseX, mouseY, delta); presetX += presetSize + presetPadding; renderedPresets++; if (renderedPresets % presetsPerLine == 0) { @@ -320,54 +322,56 @@ private void drawPresets(DrawContext context, int mouseX, int mouseY, float delt //done manually to keep list order instead of looping through Formatting.values() public void addDefaultPresets() { - ColorPresetWidget darkRed = ColorPresetWidget.fromFormatting(this, Formatting.DARK_RED); - ColorPresetWidget red = ColorPresetWidget.fromFormatting(this, Formatting.RED); - ColorPresetWidget gold = ColorPresetWidget.fromFormatting(this, Formatting.GOLD); - ColorPresetWidget yellow = ColorPresetWidget.fromFormatting(this, Formatting.YELLOW); - ColorPresetWidget green = ColorPresetWidget.fromFormatting(this, Formatting.GREEN); - ColorPresetWidget darkGreen = ColorPresetWidget.fromFormatting(this, Formatting.DARK_GREEN); - ColorPresetWidget aqua = ColorPresetWidget.fromFormatting(this, Formatting.AQUA); - ColorPresetWidget darkAqua = ColorPresetWidget.fromFormatting(this, Formatting.DARK_AQUA); - ColorPresetWidget blue = ColorPresetWidget.fromFormatting(this, Formatting.BLUE); - ColorPresetWidget darkBlue = ColorPresetWidget.fromFormatting(this, Formatting.DARK_BLUE); - ColorPresetWidget lightPurple = ColorPresetWidget.fromFormatting(this, Formatting.LIGHT_PURPLE); - ColorPresetWidget darkPurple = ColorPresetWidget.fromFormatting(this, Formatting.DARK_PURPLE); - ColorPresetWidget white = ColorPresetWidget.fromFormatting(this, Formatting.WHITE); - ColorPresetWidget grey = ColorPresetWidget.fromFormatting(this, Formatting.GRAY); - ColorPresetWidget darkGrey = ColorPresetWidget.fromFormatting(this, Formatting.DARK_GRAY); - ColorPresetWidget black = ColorPresetWidget.fromFormatting(this, Formatting.BLACK); + ColorPresetWidget darkRed = ColorPresetWidget.fromFormatting(this, ChatFormatting.DARK_RED); + ColorPresetWidget red = ColorPresetWidget.fromFormatting(this, ChatFormatting.RED); + ColorPresetWidget gold = ColorPresetWidget.fromFormatting(this, ChatFormatting.GOLD); + ColorPresetWidget yellow = ColorPresetWidget.fromFormatting(this, ChatFormatting.YELLOW); + ColorPresetWidget green = ColorPresetWidget.fromFormatting(this, ChatFormatting.GREEN); + ColorPresetWidget darkGreen = ColorPresetWidget.fromFormatting(this, ChatFormatting.DARK_GREEN); + ColorPresetWidget aqua = ColorPresetWidget.fromFormatting(this, ChatFormatting.AQUA); + ColorPresetWidget darkAqua = ColorPresetWidget.fromFormatting(this, ChatFormatting.DARK_AQUA); + ColorPresetWidget blue = ColorPresetWidget.fromFormatting(this, ChatFormatting.BLUE); + ColorPresetWidget darkBlue = ColorPresetWidget.fromFormatting(this, ChatFormatting.DARK_BLUE); + ColorPresetWidget lightPurple = ColorPresetWidget.fromFormatting(this, ChatFormatting.LIGHT_PURPLE); + ColorPresetWidget darkPurple = ColorPresetWidget.fromFormatting(this, ChatFormatting.DARK_PURPLE); + ColorPresetWidget white = ColorPresetWidget.fromFormatting(this, ChatFormatting.WHITE); + ColorPresetWidget grey = ColorPresetWidget.fromFormatting(this, ChatFormatting.GRAY); + ColorPresetWidget darkGrey = ColorPresetWidget.fromFormatting(this, ChatFormatting.DARK_GRAY); + ColorPresetWidget black = ColorPresetWidget.fromFormatting(this, ChatFormatting.BLACK); this.presetWidgets.addAll(List.of(darkRed, red, gold, yellow, green, darkGreen, aqua, darkAqua, blue, darkBlue, lightPurple, darkPurple, white, grey, darkGrey, black)); } @Override - public void onClick(double mouseX, double mouseY) { + public void onClick(MouseButtonEvent event, boolean doubleClick) { this.mouseDown = true; this.satLightDown = false; this.hueDown = false; this.presetDown = false; this.confirmOrCancelButtonDown = false; - setColorFromMouse(mouseX, mouseY); + setColorFromMouse(event, doubleClick); } - public void setColorFromMouse(double mouseX, double mouseY) { + public void setColorFromMouse(MouseButtonEvent event, boolean doubleClick) { int colorAlpha = color.getAlpha(); + double mouseX = event.x(); + double mouseY = event.y(); if (clickedSatLight(mouseX, mouseY)) { setSatLightFromMouse(mouseX, mouseY); } else if (clickedHue(mouseX, mouseY)) { setHueFromMouse(mouseX); } else if (this.confirmButton.isMouseOver(mouseX, mouseY)) { if (satLightDown || hueDown || presetDown || confirmOrCancelButtonDown) return; - this.confirmButton.onClick(mouseX, mouseY); + this.confirmButton.onClick(event, doubleClick); confirmOrCancelButtonDown = true; } else if (this.cancelButton.isMouseOver(mouseX, mouseY)) { if (satLightDown || hueDown || presetDown || confirmOrCancelButtonDown) return; - this.cancelButton.onClick(mouseX, mouseY); + this.cancelButton.onClick(event, doubleClick); confirmOrCancelButtonDown = true; } else { //clickedPreset also sets the preset to avoid an extra calculation - checkAndSetPreset(mouseX, mouseY); + checkAndSetPreset(event, doubleClick); } if (this.changeListener != null) { @@ -406,13 +410,13 @@ public boolean clickedHue(double mouseX, double mouseY) { return hueDown; } - public boolean checkAndSetPreset(double mouseX, double mouseY) { + public boolean checkAndSetPreset(MouseButtonEvent event, boolean doubleClick) { if (satLightDown || hueDown || presetDown || confirmOrCancelButtonDown) return false; //just checks for each preset here, and also sets here so it doesn't have to check again for (ColorPresetWidget preset : this.presetWidgets) { - if (preset.isMouseOver(mouseX, mouseY)) { - preset.onClick(mouseX, mouseY); + if (preset.isMouseOver(event.x(), event.y())) { + preset.onClick(event, doubleClick); //even though the preset closes the color picker, //this is added to prevent spamming tags when holding down the mouse button presetDown = true; @@ -422,14 +426,14 @@ public boolean checkAndSetPreset(double mouseX, double mouseY) { } @Override - protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY) { - if (mouseDown || isMouseOver(mouseX, mouseY)) { - setColorFromMouse(mouseX, mouseY); + protected void onDrag(MouseButtonEvent event, double dx, double dy) { + if (mouseDown || isMouseOver(event.x(), event.y())) { + setColorFromMouse(event, false); } } @Override - public void onRelease(double mouseX, double mouseY) { + public void onRelease(MouseButtonEvent event) { this.mouseDown = false; } @@ -439,7 +443,9 @@ public boolean isMouseOver(double mouseX, double mouseY) { } @Override - public void onPress() {} + public void onPress(InputWithModifiers input) { + } + public void setSatLightFromMouse(double mouseX, double mouseY) { if (mouseX < satLightX) { @@ -529,15 +535,15 @@ protected float[] getHSL() { } @Override - public void appendClickableNarrations(NarrationMessageBuilder builder) { - this.appendDefaultNarrations(builder); + public void updateWidgetNarration(NarrationElementOutput builder) { + this.defaultButtonNarrationText(builder); } public void setChangeListener(Consumer changeListener) { this.changeListener = changeListener; } - public void setPresetListener(BiConsumer presetListener) { + public void setPresetListener(BiConsumer presetListener) { this.presetListener = presetListener; } @@ -549,7 +555,7 @@ public void setOnCancel(Consumer onCancel) { this.onCancel = onCancel; } - public BiConsumer getPresetListener() { + public BiConsumer getPresetListener() { return presetListener; } @@ -592,7 +598,7 @@ public ColorPickerWidget.Builder withPreset(boolean includeDefault, Color... pre } public ColorPickerWidget build() { - ColorPickerWidget colorPickerWidget = new ColorPickerWidget(this.screen, this.x, this.y, this.width, this.height, Text.of("")); + ColorPickerWidget colorPickerWidget = new ColorPickerWidget(this.screen, this.x, this.y, this.width, this.height, Component.nullToEmpty("")); colorPickerWidget.setIncludePresets(this.includePresets); if (this.includePresets) { colorPickerWidget.setPresets(this.includeDefaultPresets, this.presets); diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPresetWidget.java b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPresetWidget.java index f9f68618..6930363d 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPresetWidget.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/ColorPresetWidget.java @@ -1,24 +1,25 @@ package dev.hephaestus.glowcase.client.gui.widget.ingame; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; -import net.minecraft.client.gui.widget.PressableWidget; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; +import net.minecraft.client.input.InputWithModifiers; import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.function.BiConsumer; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.network.chat.Component; -public class ColorPresetWidget extends PressableWidget { +public class ColorPresetWidget extends AbstractButton { public final ColorPickerWidget colorPickerWidget; public final Color color; @Nullable - public Formatting formatting = null; + public ChatFormatting formatting = null; public int z = 0; public ColorPresetWidget(ColorPickerWidget colorPicker, int x, int y, int width, int height, Color color) { - super(x, y, width, height, Text.of("")); + super(x, y, width, height, Component.nullToEmpty("")); this.colorPickerWidget = colorPicker; this.color = color; } @@ -26,14 +27,14 @@ public ColorPresetWidget(ColorPickerWidget colorPicker, int x, int y, int width, public void setPosition(int x, int y, int z, int size) { this.setX(x); this.setY(y); - this.setDimensions(size, size); + this.setSize(size, size); this.z = z; } - public static ColorPresetWidget fromFormatting(ColorPickerWidget colorPicker, Formatting formatting) { + public static ColorPresetWidget fromFormatting(ColorPickerWidget colorPicker, ChatFormatting formatting) { if(formatting.isColor()) { //noinspection DataFlowIssue - ColorPresetWidget presetWidget = new ColorPresetWidget(colorPicker,0, 0, 0, 0, new Color(formatting.getColorValue())); + ColorPresetWidget presetWidget = new ColorPresetWidget(colorPicker,0, 0, 0, 0, new Color(formatting.getColor())); presetWidget.formatting = formatting; return presetWidget; } @@ -45,14 +46,14 @@ public static ColorPresetWidget fromColor(ColorPickerWidget colorPicker, Color c } @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + protected void renderContents(GuiGraphics context, int mouseX, int mouseY, float delta) { context.fill(this.getX(), this.getY(), this.getX() + this.getWidth(), this.getY() + this.getHeight(), this.color.getRGB()); if(isMouseOver(mouseX, mouseY)) { drawOutline(context, this.getX() - 1, this.getY() - 1, this.getWidth() + 2, this.getHeight() + 2, this.z + 1); } } - private void drawOutline(DrawContext context, int x, int y, int width, int height, int z) { + private void drawOutline(GuiGraphics context, int x, int y, int width, int height, int z) { int color = Color.white.getRGB(); context.fill(x, y, x + width, y + 1, color); context.fill(x, y, x + 1, y + height, color); @@ -61,8 +62,8 @@ private void drawOutline(DrawContext context, int x, int y, int width, int heigh } @Override - public void onPress() { - BiConsumer presetListener = this.colorPickerWidget.getPresetListener(); + public void onPress(InputWithModifiers input) { + BiConsumer presetListener = this.colorPickerWidget.getPresetListener(); if(presetListener != null) { presetListener.accept(this.color, this.formatting != null && this.formatting.isColor() ? this.formatting : null); } else { @@ -77,7 +78,7 @@ public void onPress() { } @Override - protected void appendClickableNarrations(NarrationMessageBuilder builder) { + protected void updateWidgetNarration(NarrationElementOutput builder) { } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/GlowcaseTextFieldWidget.java b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/GlowcaseTextFieldWidget.java index 61edf048..f860850d 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/GlowcaseTextFieldWidget.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/GlowcaseTextFieldWidget.java @@ -1,21 +1,21 @@ package dev.hephaestus.glowcase.client.gui.widget.ingame; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; -public class GlowcaseTextFieldWidget extends TextFieldWidget { - public GlowcaseTextFieldWidget(TextRenderer textRenderer, int width, int height, Text text) { +public class GlowcaseTextFieldWidget extends EditBox { + public GlowcaseTextFieldWidget(Font textRenderer, int width, int height, Component text) { super(textRenderer, width, height, text); } - public GlowcaseTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, Text text) { + public GlowcaseTextFieldWidget(Font textRenderer, int x, int y, int width, int height, Component text) { super(textRenderer, x, y, width, height, text); } - public GlowcaseTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, @Nullable TextFieldWidget copyFrom, Text text) { + public GlowcaseTextFieldWidget(Font textRenderer, int x, int y, int width, int height, @Nullable EditBox copyFrom, Component text) { super(textRenderer, x, y, width, height, copyFrom, text); } @@ -24,12 +24,12 @@ public void setFocused(boolean focused) { boolean wasFocused = isFocused(); super.setFocused(focused); if (focused != wasFocused) { - this.onChanged(this.getText()); + this.onValueChange(this.getValue()); } } @Override - public void setPlaceholder(Text placeholder) { - super.setPlaceholder(placeholder.copy().formatted(Formatting.GRAY, Formatting.ITALIC)); + public void setHint(Component placeholder) { + super.setHint(placeholder.copy().withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC)); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/IconButtonWidget.java b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/IconButtonWidget.java index e65a6360..ca6b0837 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/IconButtonWidget.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/IconButtonWidget.java @@ -2,14 +2,14 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; -public class IconButtonWidget extends ButtonWidget { +public class IconButtonWidget extends Button { public Identifier icon; @Nullable public Identifier hoverIcon; @@ -17,12 +17,12 @@ public class IconButtonWidget extends ButtonWidget { public int iconHeight; public int z; - public static IconButtonWidget.Builder builder(Identifier icon, ButtonWidget.PressAction onPress) { + public static IconButtonWidget.Builder builder(Identifier icon, Button.OnPress onPress) { return new IconButtonWidget.Builder(icon, onPress); } - public IconButtonWidget(int x, int y, int width, int height, int iconWidth, int iconHeight, Identifier icon, @Nullable Identifier hoverIcon, PressAction onPress) { - super(x, y, width, height, Text.of(""), onPress, ButtonWidget.DEFAULT_NARRATION_SUPPLIER); + public IconButtonWidget(int x, int y, int width, int height, int iconWidth, int iconHeight, Identifier icon, @Nullable Identifier hoverIcon, OnPress onPress) { + super(x, y, width, height, Component.nullToEmpty(""), onPress, Button.DEFAULT_NARRATION); this.icon = icon; this.hoverIcon = hoverIcon; this.iconWidth = iconWidth; @@ -30,18 +30,18 @@ public IconButtonWidget(int x, int y, int width, int height, int iconWidth, int } @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + protected void renderContents(GuiGraphics context, int mouseX, int mouseY, float delta) { Identifier drawnIcon = this.icon; if(this.hoverIcon != null && this.isMouseOver(mouseX, mouseY)) { drawnIcon = this.hoverIcon; } - context.drawGuiTexture(RenderPipelines.GUI_TEXTURED, drawnIcon, this.getX(), this.getY(), this.iconWidth, this.iconHeight); + context.blitSprite(RenderPipelines.GUI_TEXTURED, drawnIcon, this.getX(), this.getY(), this.iconWidth, this.iconHeight); } public void setPosition(int x, int y, int z, int size, int iconSize) { this.setX(x); this.setY(y); - this.setDimensions(size, size); + this.setSize(size, size); this.iconWidth = iconSize; this.iconHeight = iconSize; this.z = z; @@ -52,7 +52,7 @@ public static class Builder { private final Identifier icon; @Nullable private Identifier hoverIcon = null; - private final ButtonWidget.PressAction onPress; + private final Button.OnPress onPress; private int x; private int y; private int iconWidth = 16; @@ -60,7 +60,7 @@ public static class Builder { private int width = 150; private int height = 150; - public Builder(Identifier icon, ButtonWidget.PressAction onPress) { + public Builder(Identifier icon, Button.OnPress onPress) { this.icon = icon; this.onPress = onPress; } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/SuggestionListWidget.java b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/SuggestionListWidget.java index 22724751..632f1c49 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/SuggestionListWidget.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/SuggestionListWidget.java @@ -5,153 +5,156 @@ import java.util.function.Consumer; import java.util.function.Function; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.FilterMode; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.util.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.events.ContainerEventHandler; +import net.minecraft.client.gui.navigation.ScreenRectangle; +import net.minecraft.client.gui.render.TextureSetup; +import net.minecraft.client.gui.render.state.GuiElementRenderState; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; import com.mojang.blaze3d.pipeline.RenderPipeline; +import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.pipeline.TextureTarget; +import com.mojang.blaze3d.resource.CrossFrameResourcePool; +import com.mojang.blaze3d.vertex.VertexConsumer; import dev.hephaestus.glowcase.util.MathUtils; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gl.Framebuffer; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gl.SimpleFramebuffer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ParentElement; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.SimpleGuiElementRenderState; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.client.util.Pool; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.Matrix3x2fStack; import org.lwjgl.glfw.GLFW; -public class SuggestionListWidget extends ClickableWidget { - public static final Identifier BLUR_ID = Identifier.ofVanilla("blur"); - public static final Framebuffer FRAMEBUFFER = new SimpleFramebuffer("Glowcase Suggestions", 1, 1, false); - public static final Pool POOL = new Pool(3); - private final TextRenderer textRenderer; - private final MinecraftClient client; +public class SuggestionListWidget extends AbstractWidget { + public static final Identifier BLUR_ID = Identifier.withDefaultNamespace("blur"); + public static final RenderTarget FRAMEBUFFER = new TextureTarget("Glowcase Suggestions", 1, 1, false); + public static final CrossFrameResourcePool POOL = new CrossFrameResourcePool(3); + private final Font textRenderer; + private final Minecraft client; private final List suggestions = new ArrayList<>(); private int selectedItem = -1; - private final @Nullable TextFieldWidget textFieldWidget; + private final @Nullable EditBox textFieldWidget; private @NotNull String filter = ""; - private int scrollOffset = 0; + private int scrollOffset = 0; - private final int baseLineHeight; - private final int padding; - private final int maxRows; + private final int baseLineHeight; + private final int padding; + private final int maxRows; /** * The approximate maximum number of characters that'll fit inside the width of this widget */ private int characterWidth; - private final Consumer onSelect; - private final Function toStringFunction; - - public boolean draggingScrollbar = false; - private int scrollbarDragStartY = 0; - private int initialScrollOffset = 0; + private final Consumer onSelect; + private final Function toStringFunction; + + public boolean draggingScrollbar = false; + private int scrollbarDragStartY = 0; + private int initialScrollOffset = 0; - public SuggestionListWidget(@Nullable TextFieldWidget widget, TextRenderer textRenderer, int x, int y, int width, int height, int baseLineHeight, int padding, int maxRows, Consumer onSelect, Function toStringFunction) { - super(x, y, width, height, Text.empty()); + public SuggestionListWidget(@Nullable EditBox widget, Font textRenderer, int x, int y, int width, int height, int baseLineHeight, int padding, int maxRows, Consumer onSelect, Function toStringFunction) { + super(x, y, width, height, Component.empty()); this.textFieldWidget = widget; - this.client = MinecraftClient.getInstance(); + this.client = Minecraft.getInstance(); - this.baseLineHeight = baseLineHeight; - this.padding = padding; - this.maxRows = maxRows; - this.onSelect = onSelect; - this.toStringFunction = toStringFunction; - this.textRenderer = textRenderer; + this.baseLineHeight = baseLineHeight; + this.padding = padding; + this.maxRows = maxRows; + this.onSelect = onSelect; + this.toStringFunction = toStringFunction; + this.textRenderer = textRenderer; this.characterWidth = 1; setWidth(width); - } + } - public static SuggestionListWidget forTextField(TextFieldWidget textField, TextRenderer textRenderer, Function toStringFunction) { + public static SuggestionListWidget forTextField(EditBox textField, Font textRenderer, Function toStringFunction) { return new SuggestionListWidget<>( textField, textRenderer, textField.getX(), textField.getY() + textField.getHeight() + 5, textField.getWidth(), 100, 10, 4, 5, - a -> textField.setText(toStringFunction.apply(a)), + a -> textField.setValue(toStringFunction.apply(a)), toStringFunction ); } - public static SuggestionListWidget forTextFieldWithStaticSuggestions(TextFieldWidget textField, TextRenderer textRenderer, List suggestions, Function toStringFunction, @Nullable ParentElement parent) { + public static SuggestionListWidget forTextFieldWithStaticSuggestions(EditBox textField, Font textRenderer, List suggestions, Function toStringFunction, @Nullable ContainerEventHandler parent) { var suggestionWidget = forTextField(textField, textRenderer, toStringFunction); - textField.setChangedListener((text) -> suggestionWidget.updateSuggestions(suggestions, text, parent)); + textField.setResponder((text) -> suggestionWidget.updateSuggestions(suggestions, text, parent)); return suggestionWidget; } @Override public void setWidth(int width) { super.setWidth(width); - while (textRenderer.getWidth("m".repeat(characterWidth)) < this.width) { + while (textRenderer.width("m".repeat(characterWidth)) < this.width) { characterWidth++; } } - public void updateSuggestions(List newSuggestions, String filter, @Nullable ParentElement parent) { + public void updateSuggestions(List newSuggestions, String filter, @Nullable ContainerEventHandler parent) { updateSuggestions(newSuggestions, filter, true, parent); } // update the suggestion list based on filter - public void updateSuggestions(List newSuggestions, String filter, boolean strict, @Nullable ParentElement parent) { - suggestions.clear(); + public void updateSuggestions(List newSuggestions, String filter, boolean strict, @Nullable ContainerEventHandler parent) { + suggestions.clear(); this.filter = filter; - for (T suggestion : newSuggestions) { + for (T suggestion : newSuggestions) { if (suggestion == null) { throw new NullPointerException("A suggestion can not be null!"); } - String text = toStringFunction.apply(suggestion); + String text = toStringFunction.apply(suggestion); - if (strict ? text.startsWith(filter) : text.contains(filter)) { - suggestions.add(suggestion); - } - } + if (strict ? text.startsWith(filter) : text.contains(filter)) { + suggestions.add(suggestion); + } + } - // if there is only 1 suggestion & it's equal to input, hide the list - if (suggestions.size() == 1 && toStringFunction.apply(suggestions.getFirst()).equals(filter)) { - suggestions.clear(); - } + // if there is only 1 suggestion & it's equal to input, hide the list + if (suggestions.size() == 1 && toStringFunction.apply(suggestions.getFirst()).equals(filter)) { + suggestions.clear(); + } - scrollOffset = 0; + scrollOffset = 0; if (suggestions.isEmpty()) { FRAMEBUFFER.resize(1, 1); } this.setFocused(!suggestions.isEmpty()); - } + } - @Override - public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - if (suggestions.isEmpty()) return; + @Override + public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delta) { + if (suggestions.isEmpty()) return; if (textFieldWidget != null && !textFieldWidget.isFocused()) { this.suggestions.clear(); this.setFocused(false); } - context.createNewRootLayer(); - context.state.addSimpleElement(new SimpleGuiElementRenderState() { + context.nextStratum(); + context.guiRenderState.submitGuiElement(new GuiElementRenderState() { @Override - public void setupVertices(VertexConsumer vertices, float depth) { - Matrix3x2fStack matrix = context.getMatrices(); - vertices.vertex(matrix, 0, 0, depth).texture(0, 0).color(0xFFFFFFFF); - vertices.vertex(matrix, 0, 1, depth).texture(0, 1).color(0xFFFFFFFF); - vertices.vertex(matrix, 1, 1, depth).texture(1, 1).color(0xFFFFFFFF); - vertices.vertex(matrix, 1, 0, depth).texture(1, 0).color(0xFFFFFFFF); + public void buildVertices(VertexConsumer vertices) { + Matrix3x2fStack matrix = context.pose(); + vertices.addVertexWith2DPose(matrix, 0, 0).setUv(0, 0).setColor(0xFFFFFFFF); + vertices.addVertexWith2DPose(matrix, 0, 1).setUv(0, 1).setColor(0xFFFFFFFF); + vertices.addVertexWith2DPose(matrix, 1, 1).setUv(1, 1).setColor(0xFFFFFFFF); + vertices.addVertexWith2DPose(matrix, 1, 0).setUv(1, 0).setColor(0xFFFFFFFF); } @Override @@ -161,30 +164,30 @@ public RenderPipeline pipeline() { @Override public TextureSetup textureSetup() { - return TextureSetup.withoutGlTexture(FRAMEBUFFER.getColorAttachmentView()); + return TextureSetup.singleTexture(FRAMEBUFFER.getColorTextureView(), RenderSystem.getSamplerCache().getClampToEdge(FilterMode.NEAREST)); } @Override - public @Nullable ScreenRect scissorArea() { + public @Nullable ScreenRectangle scissorArea() { return null; } @Override - public @Nullable ScreenRect bounds() { - return ScreenRect.empty(); + public @Nullable ScreenRectangle bounds() { + return ScreenRectangle.empty(); } }); - context.createNewRootLayer(); - context.getMatrices().pushMatrix(); + context.nextStratum(); + context.pose().pushMatrix(); int bgColor = 0x90000000; - int adjustedLineHeight = baseLineHeight + padding * 2; - int rows = Math.min(suggestions.size(), maxRows); - int dynamicHeight = rows * adjustedLineHeight; + int adjustedLineHeight = baseLineHeight + padding * 2; + int rows = Math.min(suggestions.size(), maxRows); + int dynamicHeight = rows * adjustedLineHeight; - boolean scrollable = suggestions.size() > maxRows; - int totalLines = suggestions.size(); + boolean scrollable = suggestions.size() > maxRows; + int totalLines = suggestions.size(); int listWidth = scrollable ? this.getWidth() - 5 - 10 : this.getWidth(); @@ -192,303 +195,311 @@ public TextureSetup textureSetup() { int y = SuggestionListWidget.this.getY(); context.enableScissor(x, y, x + listWidth, y + dynamicHeight); - context.drawTexturedQuad(RenderPipelines.GUI_TEXTURED, FRAMEBUFFER.getColorAttachmentView(), 0, 0, FRAMEBUFFER.textureWidth / this.client.getWindow().getScaleFactor(), FRAMEBUFFER.textureHeight / this.client.getWindow().getScaleFactor(), 0, 1, 0, 1, -1); - - context.fill(x, y, x + listWidth, y + dynamicHeight, bgColor); - - drawOutline(context, x, y, listWidth, dynamicHeight, 0xFFFFFFFF); - - if (scrollOffset > totalLines - rows) { - scrollOffset = Math.max(0, totalLines - rows); - } - - // render each suggestion - for (int i = 0; i < rows; i++) { - int suggestionIndex = i + scrollOffset; - if (suggestionIndex >= totalLines) break; - - T suggestion = suggestions.get(suggestionIndex); - String suggestionText = toStringFunction.apply(suggestion); - int suggestionY = y + i * adjustedLineHeight; - - // highlight hovered suggestion + context.submitBlit(RenderPipelines.GUI_TEXTURED, FRAMEBUFFER.getColorTextureView(), RenderSystem.getSamplerCache().getClampToEdge(FilterMode.NEAREST),0, 0, FRAMEBUFFER.width / this.client.getWindow().getGuiScale(), FRAMEBUFFER.height / this.client.getWindow().getGuiScale(), 0, 1, 0, 1, -1); + + context.fill(x, y, x + listWidth, y + dynamicHeight, bgColor); + + drawOutline(context, x, y, listWidth, dynamicHeight, 0xFFFFFFFF); + + if (scrollOffset > totalLines - rows) { + scrollOffset = Math.max(0, totalLines - rows); + } + + // render each suggestion + for (int i = 0; i < rows; i++) { + int suggestionIndex = i + scrollOffset; + if (suggestionIndex >= totalLines) break; + + T suggestion = suggestions.get(suggestionIndex); + String suggestionText = toStringFunction.apply(suggestion); + int suggestionY = y + i * adjustedLineHeight; + + // highlight hovered suggestion boolean hover = mouseX >= x && mouseX <= x + listWidth && mouseY >= suggestionY && mouseY < suggestionY + adjustedLineHeight; if (hover || suggestionIndex == selectedItem) { - context.fill(x, suggestionY, x + listWidth, suggestionY + adjustedLineHeight, 0xFF217C08); - drawOutline(context, x, suggestionY, listWidth, adjustedLineHeight, 0xFFFFFFFF); - } + context.fill(x, suggestionY, x + listWidth, suggestionY + adjustedLineHeight, 0xFF217C08); + drawOutline(context, x, suggestionY, listWidth, adjustedLineHeight, 0xFFFFFFFF); + } - // detect if the text is too long AND if the item is hovered, then scroll, otherwise don't - if (textRenderer.getWidth(suggestionText) > (this.getWidth() - padding - 20)) { - drawOverflowText(context, textRenderer, Text.literal(suggestionText), x + padding, suggestionY + padding - 2, x + listWidth - padding, suggestionY + adjustedLineHeight, 0xFFFFFFFF, hover); - } else { - context.drawTextWithShadow(textRenderer, Text.literal(suggestionText), x + padding, suggestionY + padding + 1, 0xFFFFFFFF); - } - } + // detect if the text is too long AND if the item is hovered, then scroll, otherwise don't + if (textRenderer.width(suggestionText) > (this.getWidth() - padding - 20)) { + drawOverflowText(context, textRenderer, Component.literal(suggestionText), x + padding, suggestionY + padding - 2, x + listWidth - padding, suggestionY + adjustedLineHeight, 0xFFFFFFFF, hover); + } else { + context.drawString(textRenderer, Component.literal(suggestionText), x + padding, suggestionY + padding + 1, 0xFFFFFFFF); + } + } - context.disableScissor(); + context.disableScissor(); - // scrollbar thingy - if (scrollable) { - int scrollbarWidth = 10; + // scrollbar thingy + if (scrollable) { + int scrollbarWidth = 10; - int sbX = x + listWidth + 5; + int sbX = x + listWidth + 5; context.enableScissor(sbX, y, sbX + scrollbarWidth, y + dynamicHeight); - context.drawTexturedQuad(RenderPipelines.GUI_TEXTURED, FRAMEBUFFER.getColorAttachmentView(), 0, 0, FRAMEBUFFER.textureWidth / this.client.getWindow().getScaleFactor(), FRAMEBUFFER.textureHeight / this.client.getWindow().getScaleFactor(), 0, 1, 0, 1, -1); - - context.fill(sbX, y, sbX + scrollbarWidth, y + dynamicHeight, bgColor); - context.disableScissor(); - - drawOutline(context, sbX, y, scrollbarWidth, dynamicHeight, 0xFFFFFFFF); - - float visibleRatio = (float) rows / totalLines; - int handleHeight = Math.max((int)(visibleRatio * (dynamicHeight - 2 * 2)), 4); - - int availableScroll = totalLines - rows; - int handleYOffset = availableScroll > 0 ? (int)(((float)scrollOffset / availableScroll) * ((dynamicHeight - 2 * 2) - handleHeight)) : 0; - int handleX = sbX + 2; - int handleY = y + 2 + handleYOffset; - int handleWidth = scrollbarWidth - 2 * 2; - - context.fill(handleX, handleY, handleX + handleWidth, handleY + handleHeight, 0xFFFFFFFF); - } - - context.getMatrices().popMatrix(); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - boolean scrollable = suggestions.size() > maxRows; - - int adjustedLineHeight = baseLineHeight + padding * 2; - int listWidth = scrollable ? this.getWidth() - 5 - 10 : this.getWidth(); - - int relativeY = (int)mouseY - this.getY(); - int clickedIndex = relativeY / adjustedLineHeight + scrollOffset; - - if (scrollable) { - int sbX = getX() + listWidth + 5; - int sbY = getY(); - int scrollbarHeight = Math.min(suggestions.size(), maxRows) * adjustedLineHeight; - - if (mouseX >= sbX && mouseX <= sbX + 10 && mouseY >= sbY && mouseY <= sbY + scrollbarHeight) { - draggingScrollbar = true; - - scrollbarDragStartY = (int) mouseY; - initialScrollOffset = scrollOffset; - - return true; - } - } - - if (mouseX >= this.getX() && mouseX <= this.getX() + listWidth) { - if (clickedIndex >= 0 && clickedIndex < suggestions.size()) { - onSelect.accept(suggestions.get(clickedIndex)); - return true; - } - } - - return false; - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - if (draggingScrollbar) { - int adjustedLineHeight = baseLineHeight + padding * 2; - int rows = Math.min(suggestions.size(), maxRows); - - int dynamicHeight = rows * adjustedLineHeight; - int totalLines = suggestions.size(); - int availableScroll = totalLines - maxRows; - - float visibleRatio = (float) maxRows / totalLines; - int handleHeight = Math.max((int)(visibleRatio * (dynamicHeight - 2 * 2)), 4); - - int dragDelta = (int) (mouseY - scrollbarDragStartY); - - if ((dynamicHeight - 2 * 2) - handleHeight > 0) { - int newOffset = initialScrollOffset + (int) ((float) dragDelta / ((dynamicHeight - 2 * 2) - handleHeight) * availableScroll); - scrollOffset = Math.max(0, Math.min(newOffset, availableScroll)); - } - - return true; - } - - return false; - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - draggingScrollbar = false; - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - int rows = Math.min(suggestions.size(), maxRows); - - int totalLines = suggestions.size(); - int maxLines = rows; - scrollOffset -= (int) verticalAmount; - - if (scrollOffset < 0) scrollOffset = 0; - if (scrollOffset > totalLines - maxLines) scrollOffset = Math.max(0, totalLines - maxLines); - - return true; - } - - @Override - protected void appendClickableNarrations(net.minecraft.client.gui.screen.narration.NarrationMessageBuilder builder) {} - - @Override - public boolean isMouseOver(double mouseX, double mouseY) { - int adjustedLineHeight = baseLineHeight + padding * 2; - int rows = Math.min(suggestions.size(), maxRows); - int dynamicHeight = rows * adjustedLineHeight; - - boolean scrollable = suggestions.size() > maxRows; - int listWidth = scrollable ? this.getWidth() - 5 - 10 : this.getWidth(); - - boolean overList = (mouseX >= this.getX() && mouseX <= this.getX() + listWidth && mouseY >= this.getY() && mouseY < this.getY() + dynamicHeight); - boolean overScrollbar = false; - - if (scrollable) { - int sbX = this.getX() + listWidth + 5; - int sbY = this.getY(); - - overScrollbar = (mouseX >= sbX && mouseX <= sbX + 10 && mouseY >= sbY && mouseY <= sbY + dynamicHeight); - } - - return overList || overScrollbar; - } - - private void drawOutline(DrawContext context, int x, int y, int width, int height, int color) { - context.fill(x, y, x + width, y + 1, color); - context.fill(x, y + height - 1, x + width, y + height, color); - context.fill(x, y, x + 1, y + height, color); - context.fill(x + width - 1, y, x + width, y + height, color); - } - - // similar to drawScrollableText but not centered - private void drawOverflowText(DrawContext context, TextRenderer textRenderer, Text text, int startX, int startY, int endX, int endY, int color, boolean hovered) { - int textRendererWidth = textRenderer.getWidth(text); - int availableWidth = endX - startX; - int y = startY + ((endY - startY) - 9) / 2; - - // if hovered, we scroll - if (hovered) { - int extra = textRendererWidth - availableWidth; - double time = Util.getMeasuringTimeMs() / 1000.0; - double period = Math.max(extra / 8.0, 2.0); - double scroll = 0.5 - 0.5 * Math.cos(2 * Math.PI * time / period); - int offset = (int)(scroll * extra); - - context.enableScissor(startX, startY, endX, endY); - context.drawTextWithShadow(textRenderer, text, startX - offset, y, color); - context.disableScissor(); - } else { - // otherwise try to shorten the text as much as possible - String rawText = text.getString(); - - String collapsedText; - int colonIndex = rawText.indexOf(':'); - - // if no colon, prob nothing to collapse - if (colonIndex == -1) { - collapsedText = rawText; - } else { - int lastSlashIndex = rawText.lastIndexOf('/'); - - // if no slash after colon, leave as-is - if (lastSlashIndex == -1 || lastSlashIndex < colonIndex) { - collapsedText = rawText; - } else { - String namespace = rawText.substring(0, colonIndex + 1); - String lastPart = rawText.substring(lastSlashIndex + 1); - - collapsedText = namespace + ".../" + lastPart; - } - } - - String finalText; - if (filter.trim().isEmpty()) { - finalText = collapsedText; - } else if (filter.length() >= (rawText.indexOf(':') + 1)) { - if (rawText.lastIndexOf('/') == -1) { - //... and no slash, put ... before - finalText = "..." + collapsedText.substring(rawText.indexOf(':') + 1); - } else { - // no namespace - finalText = collapsedText.substring(rawText.indexOf(':') + 1); - } - } else if (filter.length() > 1) { - int removeCount = Math.min(filter.length(), collapsedText.length()); - finalText = "..." + collapsedText.substring(removeCount); - } else { - finalText = collapsedText; - } - - if (filter.trim().isEmpty()) { - int slashIndex = collapsedText.lastIndexOf("/"); - - if (slashIndex != -1) { - String prefix = collapsedText.substring(0, slashIndex + 1); - String lastPart = collapsedText.substring(slashIndex + 1); - - if (textRenderer.getWidth(collapsedText) > availableWidth) { - int prefixWidth = textRenderer.getWidth(prefix); - int allowedForLast = availableWidth - prefixWidth; - - if (allowedForLast < 0) { - finalText = trimToWidth(collapsedText, availableWidth, textRenderer); - } else { - if (textRenderer.getWidth(lastPart) > allowedForLast) { - lastPart = trimToWidth(lastPart, allowedForLast, textRenderer); - } - - finalText = prefix + lastPart; - } - } - } else { - finalText = trimToWidth(collapsedText, availableWidth, textRenderer); - } - } else { - if (textRenderer.getWidth(finalText) > availableWidth) { - finalText = trimToWidth(finalText, availableWidth, textRenderer); - } - } - - context.enableScissor(startX, startY, endX, endY); - context.drawTextWithShadow(textRenderer, Text.literal(finalText), startX, y, color); - context.disableScissor(); - } - } - - private String trimToWidth(String rawText, int availableWidth, TextRenderer textRenderer) { - if (textRenderer.getWidth(rawText) <= availableWidth) { - return rawText; - } - - int maxWidth = availableWidth - textRenderer.getWidth("..."); - int trimIndex = rawText.length(); - - while (trimIndex > 0 && textRenderer.getWidth(rawText.substring(0, trimIndex)) > maxWidth) { - trimIndex--; - } - - return rawText.substring(0, trimIndex) + "..."; - } + context.submitBlit(RenderPipelines.GUI_TEXTURED, FRAMEBUFFER.getColorTextureView(),RenderSystem.getSamplerCache().getClampToEdge(FilterMode.NEAREST), 0, 0, FRAMEBUFFER.width / this.client.getWindow().getGuiScale(), FRAMEBUFFER.height / this.client.getWindow().getGuiScale(), 0, 1, 0, 1, -1); + + context.fill(sbX, y, sbX + scrollbarWidth, y + dynamicHeight, bgColor); + context.disableScissor(); + + drawOutline(context, sbX, y, scrollbarWidth, dynamicHeight, 0xFFFFFFFF); + + float visibleRatio = (float) rows / totalLines; + int handleHeight = Math.max((int) (visibleRatio * (dynamicHeight - 2 * 2)), 4); + + int availableScroll = totalLines - rows; + int handleYOffset = availableScroll > 0 ? (int) (((float) scrollOffset / availableScroll) * ((dynamicHeight - 2 * 2) - handleHeight)) : 0; + int handleX = sbX + 2; + int handleY = y + 2 + handleYOffset; + int handleWidth = scrollbarWidth - 2 * 2; + + context.fill(handleX, handleY, handleX + handleWidth, handleY + handleHeight, 0xFFFFFFFF); + } + + context.pose().popMatrix(); + } + + @Override + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + var mouseX = event.x(); + var mouseY = event.y(); + + boolean scrollable = suggestions.size() > maxRows; + + int adjustedLineHeight = baseLineHeight + padding * 2; + int listWidth = scrollable ? this.getWidth() - 5 - 10 : this.getWidth(); + + int relativeY = (int) mouseY - this.getY(); + int clickedIndex = relativeY / adjustedLineHeight + scrollOffset; + + if (scrollable) { + int sbX = getX() + listWidth + 5; + int sbY = getY(); + int scrollbarHeight = Math.min(suggestions.size(), maxRows) * adjustedLineHeight; + + if (mouseX >= sbX && mouseX <= sbX + 10 && mouseY >= sbY && mouseY <= sbY + scrollbarHeight) { + draggingScrollbar = true; + + scrollbarDragStartY = (int) mouseY; + initialScrollOffset = scrollOffset; + + return true; + } + } + + if (mouseX >= this.getX() && mouseX <= this.getX() + listWidth) { + if (clickedIndex >= 0 && clickedIndex < suggestions.size()) { + onSelect.accept(suggestions.get(clickedIndex)); + return true; + } + } + + return false; + } + + @Override + public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) { + var mouseX = event.x(); + var mouseY = event.y(); + + if (draggingScrollbar) { + int adjustedLineHeight = baseLineHeight + padding * 2; + int rows = Math.min(suggestions.size(), maxRows); + + int dynamicHeight = rows * adjustedLineHeight; + int totalLines = suggestions.size(); + int availableScroll = totalLines - maxRows; + + float visibleRatio = (float) maxRows / totalLines; + int handleHeight = Math.max((int) (visibleRatio * (dynamicHeight - 2 * 2)), 4); + + int dragDelta = (int) (mouseY - scrollbarDragStartY); + + if ((dynamicHeight - 2 * 2) - handleHeight > 0) { + int newOffset = initialScrollOffset + (int) ((float) dragDelta / ((dynamicHeight - 2 * 2) - handleHeight) * availableScroll); + scrollOffset = Math.max(0, Math.min(newOffset, availableScroll)); + } + + return true; + } + + return false; + } + + @Override + public boolean mouseReleased(MouseButtonEvent event) { + draggingScrollbar = false; + return super.mouseReleased(event); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { + int rows = Math.min(suggestions.size(), maxRows); + + int totalLines = suggestions.size(); + int maxLines = rows; + scrollOffset -= (int) verticalAmount; + + if (scrollOffset < 0) scrollOffset = 0; + if (scrollOffset > totalLines - maxLines) scrollOffset = Math.max(0, totalLines - maxLines); + + return true; + } + + @Override + protected void updateWidgetNarration(net.minecraft.client.gui.narration.NarrationElementOutput builder) { + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) { + int adjustedLineHeight = baseLineHeight + padding * 2; + int rows = Math.min(suggestions.size(), maxRows); + int dynamicHeight = rows * adjustedLineHeight; + + boolean scrollable = suggestions.size() > maxRows; + int listWidth = scrollable ? this.getWidth() - 5 - 10 : this.getWidth(); + + boolean overList = (mouseX >= this.getX() && mouseX <= this.getX() + listWidth && mouseY >= this.getY() && mouseY < this.getY() + dynamicHeight); + boolean overScrollbar = false; + + if (scrollable) { + int sbX = this.getX() + listWidth + 5; + int sbY = this.getY(); + + overScrollbar = (mouseX >= sbX && mouseX <= sbX + 10 && mouseY >= sbY && mouseY <= sbY + dynamicHeight); + } + + return overList || overScrollbar; + } + + private void drawOutline(GuiGraphics context, int x, int y, int width, int height, int color) { + context.fill(x, y, x + width, y + 1, color); + context.fill(x, y + height - 1, x + width, y + height, color); + context.fill(x, y, x + 1, y + height, color); + context.fill(x + width - 1, y, x + width, y + height, color); + } + + // similar to drawScrollableText but not centered + private void drawOverflowText(GuiGraphics context, Font textRenderer, Component text, int startX, int startY, int endX, int endY, int color, boolean hovered) { + int textRendererWidth = textRenderer.width(text); + int availableWidth = endX - startX; + int y = startY + ((endY - startY) - 9) / 2; + + // if hovered, we scroll + if (hovered) { + int extra = textRendererWidth - availableWidth; + double time = Util.getMillis() / 1000.0; + double period = Math.max(extra / 8.0, 2.0); + double scroll = 0.5 - 0.5 * Math.cos(2 * Math.PI * time / period); + int offset = (int) (scroll * extra); + + context.enableScissor(startX, startY, endX, endY); + context.drawString(textRenderer, text, startX - offset, y, color); + context.disableScissor(); + } else { + // otherwise try to shorten the text as much as possible + String rawText = text.getString(); + + String collapsedText; + int colonIndex = rawText.indexOf(':'); + + // if no colon, prob nothing to collapse + if (colonIndex == -1) { + collapsedText = rawText; + } else { + int lastSlashIndex = rawText.lastIndexOf('/'); + + // if no slash after colon, leave as-is + if (lastSlashIndex == -1 || lastSlashIndex < colonIndex) { + collapsedText = rawText; + } else { + String namespace = rawText.substring(0, colonIndex + 1); + String lastPart = rawText.substring(lastSlashIndex + 1); + + collapsedText = namespace + ".../" + lastPart; + } + } + + String finalText; + if (filter.trim().isEmpty()) { + finalText = collapsedText; + } else if (filter.length() >= (rawText.indexOf(':') + 1)) { + if (rawText.lastIndexOf('/') == -1) { + //... and no slash, put ... before + finalText = "..." + collapsedText.substring(rawText.indexOf(':') + 1); + } else { + // no namespace + finalText = collapsedText.substring(rawText.indexOf(':') + 1); + } + } else if (filter.length() > 1) { + int removeCount = Math.min(filter.length(), collapsedText.length()); + finalText = "..." + collapsedText.substring(removeCount); + } else { + finalText = collapsedText; + } + + if (filter.trim().isEmpty()) { + int slashIndex = collapsedText.lastIndexOf("/"); + + if (slashIndex != -1) { + String prefix = collapsedText.substring(0, slashIndex + 1); + String lastPart = collapsedText.substring(slashIndex + 1); + + if (textRenderer.width(collapsedText) > availableWidth) { + int prefixWidth = textRenderer.width(prefix); + int allowedForLast = availableWidth - prefixWidth; + + if (allowedForLast < 0) { + finalText = trimToWidth(collapsedText, availableWidth, textRenderer); + } else { + if (textRenderer.width(lastPart) > allowedForLast) { + lastPart = trimToWidth(lastPart, allowedForLast, textRenderer); + } + + finalText = prefix + lastPart; + } + } + } else { + finalText = trimToWidth(collapsedText, availableWidth, textRenderer); + } + } else { + if (textRenderer.width(finalText) > availableWidth) { + finalText = trimToWidth(finalText, availableWidth, textRenderer); + } + } + + context.enableScissor(startX, startY, endX, endY); + context.drawString(textRenderer, Component.literal(finalText), startX, y, color); + context.disableScissor(); + } + } + + private String trimToWidth(String rawText, int availableWidth, Font textRenderer) { + if (textRenderer.width(rawText) <= availableWidth) { + return rawText; + } + + int maxWidth = availableWidth - textRenderer.width("..."); + int trimIndex = rawText.length(); + + while (trimIndex > 0 && textRenderer.width(rawText.substring(0, trimIndex)) > maxWidth) { + trimIndex--; + } + + return rawText.substring(0, trimIndex) + "..."; + } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + public boolean keyPressed(KeyEvent event) { if (suggestions.isEmpty()) { return false; } int rows = Math.min(suggestions.size(), maxRows); + var keyCode = event.key(); boolean affected = switch (keyCode) { case GLFW.GLFW_KEY_UP -> { if (this.selectedItem == -1) this.selectedItem = 0; @@ -526,10 +537,10 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { } if (textFieldWidget != null) { - return textFieldWidget.keyPressed(keyCode, scanCode, modifiers); + return textFieldWidget.keyPressed(event); } - return super.keyPressed(keyCode, scanCode, modifiers); + return super.keyPressed(event); } @Override diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/Vec3FieldsWidget.java b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/Vec3FieldsWidget.java index ce295f19..eb8cda02 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/Vec3FieldsWidget.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/widget/ingame/Vec3FieldsWidget.java @@ -1,98 +1,99 @@ package dev.hephaestus.glowcase.client.gui.widget.ingame; import dev.hephaestus.glowcase.util.ParseUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; -import net.minecraft.client.gui.widget.ContainerWidget; -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.Text; -import net.minecraft.util.math.Vec3d; - import java.util.List; - -public class Vec3FieldsWidget extends ContainerWidget { - private final TextFieldWidget x; - private final TextFieldWidget y; - private final TextFieldWidget z; - - private Vec3d value; - - public Vec3FieldsWidget(int x, int y, int width, int height, MinecraftClient client, Vec3d defaultValue) { - super(x, y, width, height, Text.empty()); - this.x = new TextFieldWidget( - client.textRenderer, +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractContainerWidget; +import net.minecraft.client.gui.components.AbstractScrollArea; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.network.chat.Component; +import net.minecraft.world.phys.Vec3; + +public class Vec3FieldsWidget extends AbstractContainerWidget { + private final EditBox x; + private final EditBox y; + private final EditBox z; + + private Vec3 value; + + public Vec3FieldsWidget(int x, int y, int width, int height, Minecraft client, Vec3 defaultValue) { + super(x, y, width, height, Component.empty(), AbstractScrollArea.defaultSettings(10)); + this.x = new EditBox( + client.font, x, y, width / 3, height, - Text.empty() + Component.empty() ); - this.y = new TextFieldWidget( - client.textRenderer, + this.y = new EditBox( + client.font, x + width / 3, y, width / 3, height, - Text.empty() + Component.empty() ); - this.z = new TextFieldWidget( - client.textRenderer, + this.z = new EditBox( + client.font, x + (width / 3 * 2), y, width / 3, height, - Text.empty() + Component.empty() ); this.value = defaultValue; - this.x.setText(String.valueOf(defaultValue.x)); - this.y.setText(String.valueOf(defaultValue.y)); - this.z.setText(String.valueOf(defaultValue.z)); + this.x.setValue(String.valueOf(defaultValue.x)); + this.y.setValue(String.valueOf(defaultValue.y)); + this.z.setValue(String.valueOf(defaultValue.z)); - this.x.setTextPredicate(ParseUtil::canParseDouble); - this.y.setTextPredicate(ParseUtil::canParseDouble); - this.z.setTextPredicate(ParseUtil::canParseDouble); + // FIXME removed in 26.1+ +// this.x.setFilter(ParseUtil::canParseDouble); +// this.y.setFilter(ParseUtil::canParseDouble); +// this.z.setFilter(ParseUtil::canParseDouble); - this.x.setChangedListener(s -> value = new Vec3d(ParseUtil.parseOrDefault(s, value.x), value.y , value.z)); - this.y.setChangedListener(s -> value = new Vec3d(value.x, ParseUtil.parseOrDefault(s, value.y), value.z)); - this.z.setChangedListener(s -> value = new Vec3d(value.x, value.y, ParseUtil.parseOrDefault(s, value.z))); + this.x.setResponder(s -> value = new Vec3(ParseUtil.parseOrDefault(s, value.x), value.y , value.z)); + this.y.setResponder(s -> value = new Vec3(value.x, ParseUtil.parseOrDefault(s, value.y), value.z)); + this.z.setResponder(s -> value = new Vec3(value.x, value.y, ParseUtil.parseOrDefault(s, value.z))); } - public void setVec(Vec3d newVec) { - this.x.setText(String.valueOf(newVec.x)); - this.y.setText(String.valueOf(newVec.y)); - this.z.setText(String.valueOf(newVec.z)); + public void setVec(Vec3 newVec) { + this.x.setValue(String.valueOf(newVec.x)); + this.y.setValue(String.valueOf(newVec.y)); + this.z.setValue(String.valueOf(newVec.z)); } @Override - public List children() { + public List children() { return List.of(x, y, z); } @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + protected void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delta) { x.renderWidget(context, mouseX, mouseY, delta); y.renderWidget(context, mouseX, mouseY, delta); z.renderWidget(context, mouseX, mouseY, delta); } @Override - protected void appendClickableNarrations(NarrationMessageBuilder builder) { - x.appendClickableNarrations(builder); - y.appendClickableNarrations(builder); - z.appendClickableNarrations(builder); + protected void updateWidgetNarration(NarrationElementOutput builder) { + x.updateWidgetNarration(builder); + y.updateWidgetNarration(builder); + z.updateWidgetNarration(builder); } - public Vec3d value() { + public Vec3 value() { return value; } @Override - protected int getContentsHeightWithPadding() { + protected int contentHeight() { return 9 + 4; //FIXME: get this right } @Override - protected double getDeltaYPerScroll() { + protected double scrollRate() { return 9.0 / 2.0; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/BakedBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/BakedBlockEntityRenderer.java index 758eb0eb..9cea79c9 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/BakedBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/BakedBlockEntityRenderer.java @@ -1,445 +1,453 @@ -package dev.hephaestus.glowcase.client.render.block.entity; - -import com.google.common.collect.Sets; -import com.mojang.blaze3d.buffers.GpuBuffer; -import com.mojang.blaze3d.buffers.GpuBufferSlice; -import com.mojang.blaze3d.pipeline.RenderPipeline; -import com.mojang.blaze3d.systems.CommandEncoder; -import com.mojang.blaze3d.systems.RenderPass; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.textures.GpuTextureView; -import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.logging.LogUtils; -import dev.hephaestus.glowcase.mixin.client.GameRendererAccessor; -import dev.hephaestus.glowcase.mixin.client.MultiPhaseRenderLayerAccessor; -import dev.hephaestus.glowcase.mixin.client.RenderLayerMultiPhaseParametersAccessor; -import it.unimi.dsi.fastutil.objects.Object2ReferenceMap; -import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; -import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.Framebuffer; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gl.ScissorState; -import net.minecraft.client.render.*; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.render.chunk.Buffers; -import net.minecraft.client.render.fog.FogRenderer; -import net.minecraft.client.util.BufferAllocator; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.profiler.Profiler; -import net.minecraft.util.profiler.Profilers; -import org.jetbrains.annotations.NotNull; -import org.joml.Vector4f; -import org.slf4j.Logger; - -import java.nio.ByteBuffer; -import java.util.*; - -public abstract class BakedBlockEntityRenderer implements BlockEntityRenderer { - protected final BlockEntityRendererFactory.Context context; - - protected BakedBlockEntityRenderer(BlockEntityRendererFactory.Context context) { - this.context = context; - } - - /** - * Handles invalidation and passing of rendered vertices to the baking system. - * Override {@link #renderBaked(BlockEntity, MatrixStack, VertexConsumerProvider, int, int)} and - * {@link #renderBaked(BlockEntity, MatrixStack, VertexConsumerProvider, int, int)} instead of this method. - */ - @Override - public final void render(T entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - renderUnbaked(entity, tickDelta, matrices, vertexConsumers, light, overlay, cameraPos); - Manager.activateRegion(entity.getPos()); - } - - /** - * Render vertices to be baked into the render region. This method will be called every time the render region is rebuilt - so - * you should only render vertices that don't move here. You can call {@link Manager#markForRebuild(BlockPos)} to - * cause the render region to be rebuilt, but do not call this too frequently as it will affect performance. - * You must use the provided VertexConsumerProvider and MatrixStack to render your vertices - any use of Tessellator - * or RenderSystem here will not work. If you need custom rendering settings, you can use a custom RenderLayer. - */ - public abstract void renderBaked(T entity, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay); - - /** - * Render vertices immediately. This works exactly the same way as a normal BER render method, and can be used for dynamic - * rendering that changes every frame. In this method you can also check for render invalidation and call {@link Manager#markForRebuild(BlockPos)} - * as appropriate. - */ - public abstract void renderUnbaked(T entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos); - - public abstract boolean shouldBake(T entity); - - private record RenderRegionPos(int x, int z, @NotNull BlockPos origin) { - public RenderRegionPos(int x, int z) { - this(x, z, new BlockPos(x << Manager.REGION_SHIFT, 0, z << Manager.REGION_SHIFT)); - } - - public RenderRegionPos(BlockPos pos) { - this(pos.getX() >> Manager.REGION_SHIFT, pos.getZ() >> Manager.REGION_SHIFT); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - RenderRegionPos that = (RenderRegionPos) o; - return x == that.x && - z == that.z; - } - - @Override - public int hashCode() { - return Objects.hash(x, z); - } - } - - public static class Manager { - // 2x2 chunks size for regions - public static final int REGION_FROMCHUNK_SHIFT = 1; - public static final int REGION_SHIFT = 4 + REGION_FROMCHUNK_SHIFT; - public static final int MAX_XZ_IN_REGION = (16 << REGION_FROMCHUNK_SHIFT) - 1; - public static final int VIEW_RADIUS = 3; - - private static final Object2ReferenceMap regions = new Object2ReferenceOpenHashMap<>(); - private static final Set needsRebuild = Sets.newHashSet(); - - private static class CachedVertexConsumerProvider implements VertexConsumerProvider { - private final Reference2ReferenceMap allocators = new Reference2ReferenceOpenHashMap<>(); - private final Reference2ReferenceMap builders = new Reference2ReferenceOpenHashMap<>(); - - @Override - public VertexConsumer getBuffer(RenderLayer layer) { - return builders.computeIfAbsent(layer, l1 -> new BufferBuilder( - allocators.computeIfAbsent(layer, l2 -> new BufferAllocator(layer.getExpectedBufferSize())), - layer.getDrawMode(), - layer.getVertexFormat())); - } - - /** - * Resets the provider so another scene can be rendered - */ - public void reset() { - allocators.forEach((layer, allocator) -> allocator.reset()); - builders.clear(); - } - } - - private static final CachedVertexConsumerProvider vcp = new CachedVertexConsumerProvider(); - - private static final Logger LOGGER = LogUtils.getLogger(); - - private static class RegionBuffer { - private final Map layerBuffers = new Reference2ReferenceOpenHashMap<>(); - private final Set uploadedLayers = new ObjectOpenHashSet<>(); - - @SuppressWarnings("DataFlowIssue") - public void render(RenderLayer layer, MatrixStack matrices) { - Framebuffer framebuffer; - if (layer instanceof RenderLayer.MultiPhase) { - framebuffer = ((RenderLayerMultiPhaseParametersAccessor) (Object) ((MultiPhaseRenderLayerAccessor) layer).getPhases()).getTarget().get(); - } else { - framebuffer = MinecraftClient.getInstance().getFramebuffer(); - } - - RenderPipeline pipeline; - if (layer instanceof RenderLayer.MultiPhase) { - pipeline = ((MultiPhaseRenderLayerAccessor) layer).getPipeline(); - } else { - pipeline = RenderPipelines.SOLID; - } - - layer.startDrawing(); - GpuBufferSlice gpuBufferSlice = RenderSystem.getDynamicUniforms() - .write( - matrices.peek().getPositionMatrix(), - new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), - RenderSystem.getModelOffset(), - RenderSystem.getTextureMatrix(), - RenderSystem.getShaderLineWidth() - ); - - try (RenderPass renderPass = RenderSystem.getDevice() - .createCommandEncoder() - .createRenderPass( - () -> "Glowcase baked BER section layers", - framebuffer.getColorAttachmentView(), - OptionalInt.empty(), - framebuffer.getDepthAttachmentView(), - OptionalDouble.empty() - )) { - Buffers buffers = layerBuffers.get(layer); - - GpuBuffer indexBuffer; - VertexFormat.IndexType indexType; - if (buffers.getIndexBuffer() == null) { - RenderSystem.ShapeIndexBuffer shapeIndexBuffer = RenderSystem.getSequentialBuffer(layer.getDrawMode()); - indexBuffer = shapeIndexBuffer.getIndexBuffer(buffers.getIndexCount()); - indexType = shapeIndexBuffer.getIndexType(); - } else { - indexBuffer = buffers.getIndexBuffer(); - indexType = buffers.getIndexType(); - } - - ScissorState scissorState = RenderSystem.getScissorStateForRenderTypeDraws(); - if (scissorState.method_72091()) { - renderPass.enableScissor(scissorState.method_72092(), scissorState.method_72093(), scissorState.method_72094(), scissorState.method_72095()); - } - - for (int j = 0; j < 12; j++) { - GpuTextureView gpuTextureView3 = RenderSystem.getShaderTexture(j); - if (gpuTextureView3 != null) { - renderPass.bindSampler("Sampler" + j, gpuTextureView3); - } - } - - renderPass.setPipeline(pipeline); - renderPass.setUniform("DynamicTransforms", gpuBufferSlice); - renderPass.setVertexBuffer(0, buffers.getVertexBuffer()); - renderPass.setIndexBuffer(indexBuffer, indexType); - RenderSystem.bindDefaultUniforms(renderPass); - - renderPass.drawIndexed(0, 0, buffers.getIndexCount(), 1); - } - layer.endDrawing(); - - //VertexBuffer buf = layerBuffers.get(layer); - //buf.bind(); - //layer.startDrawing(); - //buf.draw(matrices.peek().getPositionMatrix(), projectionMatrix, RenderSystem.getShader()); - //layer.endDrawing(); - //VertexBuffer.unbind(); - } - - public void upload(RenderLayer layer, BufferBuilder newBuf) { - try (BuiltBuffer buffer = newBuf.endNullable()) { - if (buffer == null) return; - - CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder(); - Buffers oldBuffers = this.layerBuffers.get(layer); - if (oldBuffers != null) { - if (oldBuffers.getVertexBuffer().size() < buffer.getBuffer().remaining()) { - oldBuffers.getVertexBuffer().close(); - oldBuffers.setVertexBuffer( - RenderSystem.getDevice() - .createBuffer( - () -> "Glowcase Region vertex buffer - layer: " + layer.getName(), - GpuBuffer.USAGE_VERTEX | GpuBuffer.USAGE_COPY_DST, - buffer.getBuffer() - ) - ); - } else if (!oldBuffers.getVertexBuffer().isClosed()) { - commandEncoder.writeToBuffer(oldBuffers.getVertexBuffer().slice(), buffer.getBuffer()); - } - - ByteBuffer byteBuffer = buffer.getSortedBuffer(); - if (byteBuffer != null) { - if (oldBuffers.getIndexBuffer() != null && oldBuffers.getIndexBuffer().size() >= byteBuffer.remaining()) { - if (!oldBuffers.getIndexBuffer().isClosed()) { - commandEncoder.writeToBuffer(oldBuffers.getIndexBuffer().slice(), byteBuffer); - } - } else { - if (oldBuffers.getIndexBuffer() != null) { - oldBuffers.getIndexBuffer().close(); - } - - oldBuffers.setIndexBuffer( - RenderSystem.getDevice() - .createBuffer( - () -> "Glowcase Region index buffer - layer: " + layer.getName(), - GpuBuffer.USAGE_INDEX | GpuBuffer.USAGE_COPY_DST, - byteBuffer - ) - ); - } - } else if (oldBuffers.getIndexBuffer() != null) { - oldBuffers.getIndexBuffer().close(); - oldBuffers.setIndexBuffer(null); - } - - oldBuffers.setIndexCount(buffer.getDrawParameters().indexCount()); - oldBuffers.setIndexType(buffer.getDrawParameters().indexType()); - } else { - GpuBuffer vertexBuffer = RenderSystem.getDevice() - .createBuffer( - () -> "Glowcase Region vertex buffer - layer: " + layer.getName(), - GpuBuffer.USAGE_VERTEX | GpuBuffer.USAGE_COPY_DST, - buffer.getBuffer() - ); - ByteBuffer sortedBuffer = buffer.getSortedBuffer(); - GpuBuffer indexBuffer = sortedBuffer != null - ? RenderSystem.getDevice() - .createBuffer( - () -> "Glowcase Region index buffer - layer: " + layer.getName(), - GpuBuffer.USAGE_INDEX | GpuBuffer.USAGE_COPY_DST, - sortedBuffer - ) - : null; - this.layerBuffers.put(layer, new Buffers(vertexBuffer, indexBuffer, buffer.getDrawParameters().indexCount(), buffer.getDrawParameters().indexType())); - } - - this.uploadedLayers.add(layer); - } - } - - public void reset() { - layerBuffers.values().forEach(Buffers::close); - layerBuffers.clear(); - uploadedLayers.clear(); - } - } - - /** - * Causes the render region containing this BlockEntity to be rebuilt - - * do not call this too frequently as it will affect performance. - * An invalidation will not immediately cause the next frame to contain an updated view (and call to renderBaked) - * as all render region rebuilds must call every BER that is to be rendered, otherwise they will be missing from the - * vertex buffer. - */ - public static void markForRebuild(BlockPos pos) { - needsRebuild.add(new RenderRegionPos(pos)); - } - - // TODO: move chunk baking off-thread? - - private static boolean isVisiblePos(RenderRegionPos rrp, Vec3d cam) { - return Math.abs(rrp.x - ((int) cam.getX() >> REGION_SHIFT)) <= VIEW_RADIUS && Math.abs(rrp.z - ((int) cam.getZ() >> REGION_SHIFT)) <= VIEW_RADIUS; - } - - @SuppressWarnings("unchecked") - public static void render(WorldRenderContext wrc) { - Profiler profiler = Profilers.get(); - profiler.push("glowcase:baked_block_entity_rendering"); - - Vec3d cam = wrc.camera().getPos(); - - if (!needsRebuild.isEmpty()) { - profiler.push("rebuild"); - - // Make builders for regions that are marked for rebuild, render and upload to RegionBuffers - Set removing = Sets.newHashSet(); - List blockEntities = new ArrayList<>(); - MatrixStack bakeMatrices = new MatrixStack(); - for (RenderRegionPos rrp : needsRebuild) { - if (isVisiblePos(rrp, cam)) { - // For the current region, rebuild each render layer using the buffer builders - // Find all block entities in this region - for (int chunkX = rrp.x << REGION_FROMCHUNK_SHIFT; chunkX < (rrp.x + 1) << REGION_FROMCHUNK_SHIFT; chunkX++) { - for (int chunkZ = rrp.z << REGION_FROMCHUNK_SHIFT; chunkZ < (rrp.z + 1) << REGION_FROMCHUNK_SHIFT; chunkZ++) { - blockEntities.addAll(wrc.world().getChunk(chunkX, chunkZ).getBlockEntities().values()); - } - } - - if (!blockEntities.isEmpty()) { - boolean bakedAnything = false; - - for (BlockEntity be : blockEntities) { - if (MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(be) instanceof BakedBlockEntityRenderer renderer && renderer.shouldBake(be)) { - BlockPos pos = be.getPos(); - bakeMatrices.push(); - bakeMatrices.translate(pos.getX() & MAX_XZ_IN_REGION, pos.getY(), pos.getZ() & MAX_XZ_IN_REGION); - try { - renderer.renderBaked(be, bakeMatrices, vcp, WorldRenderer.getLightmapCoordinates(wrc.world(), pos), OverlayTexture.DEFAULT_UV); - bakedAnything = true; - } catch (Throwable t) { - LOGGER.error("Block entity renderer threw exception during baking: ", t); - } - bakeMatrices.pop(); - } - } - - blockEntities.clear(); - - if (bakedAnything) { - RegionBuffer buf = regions.computeIfAbsent(rrp, k -> new RegionBuffer()); - buf.reset(); - vcp.builders.forEach(buf::upload); - vcp.reset(); - } else { - removing.add(rrp); - } - } else { - removing.add(rrp); - } - } - } - // We've processed all pending rebuilds now - needsRebuild.clear(); - // These regions no longer contain anything - removing.forEach(rrp -> { - RegionBuffer buf = regions.get(rrp); - if (buf != null) { - buf.reset(); - regions.remove(rrp, buf); - } - }); - - profiler.pop(); - } - - if (!regions.isEmpty()) { - profiler.push("render"); - - /* - * Set the fog end to an extremely high value, this is a total hack but. - * It's needed to make fog not bleed into text blocks - */ - GpuBufferSlice originalFog = RenderSystem.getShaderFog(); - RenderSystem.setShaderFog(((GameRendererAccessor) wrc.gameRenderer()).getFogRenderer().getFogBuffer(FogRenderer.FogType.NONE)); - // Iterate over all RegionBuffers, render visible and remove non-visible RegionBuffers - MatrixStack matrices = wrc.matrixStack(); - matrices.push(); - matrices.multiplyPositionMatrix(wrc.positionMatrix()); - matrices.translate(-cam.x, -cam.y, -cam.z); - var iter = regions.object2ReferenceEntrySet().iterator(); - while (iter.hasNext()) { - var entry = iter.next(); - RenderRegionPos rrp = entry.getKey(); - RegionBuffer regionBuffer = entry.getValue(); - if (isVisiblePos(entry.getKey(), cam)) { - // Iterate over used render layers in the region, render them - matrices.push(); - matrices.translate(rrp.origin.getX(), rrp.origin.getY(), rrp.origin.getZ()); - for (RenderLayer l : regionBuffer.uploadedLayers) { - regionBuffer.render(l, matrices); - } - matrices.pop(); - } else { - regionBuffer.reset(); - iter.remove(); - } - } - RenderSystem.setShaderFog(originalFog); - matrices.pop(); - - profiler.pop(); - } - - //RenderSystem.setShaderColor(1, 1, 1, 1); - - profiler.pop(); - } - - public static void activateRegion(BlockPos pos) { - RenderRegionPos rrp = new RenderRegionPos(pos); - if (!regions.containsKey(rrp)) { - markForRebuild(pos); - } - } - - public static void reset() { - regions.values().forEach(RegionBuffer::reset); - regions.clear(); - needsRebuild.clear(); - } - } -} +// FIXME 26.1 + +//package dev.hephaestus.glowcase.client.render.block.entity; +// +//import com.google.common.collect.Sets; +//import com.mojang.blaze3d.buffers.GpuBuffer; +//import com.mojang.blaze3d.buffers.GpuBufferSlice; +//import com.mojang.blaze3d.pipeline.RenderPipeline; +//import com.mojang.blaze3d.pipeline.RenderTarget; +//import com.mojang.blaze3d.systems.CommandEncoder; +//import com.mojang.blaze3d.systems.RenderPass; +//import com.mojang.blaze3d.systems.RenderSystem; +//import com.mojang.blaze3d.systems.ScissorState; +//import com.mojang.blaze3d.textures.GpuTextureView; +//import com.mojang.blaze3d.vertex.BufferBuilder; +//import com.mojang.blaze3d.vertex.ByteBufferBuilder; +//import com.mojang.blaze3d.vertex.MeshData; +//import com.mojang.blaze3d.vertex.PoseStack; +//import com.mojang.blaze3d.vertex.VertexConsumer; +//import com.mojang.blaze3d.vertex.VertexFormat; +//import com.mojang.logging.LogUtils; +//import dev.hephaestus.glowcase.mixin.client.GameRendererAccessor; +//import dev.hephaestus.glowcase.mixin.client.CompositeRenderTypeAccessor; +//import dev.hephaestus.glowcase.mixin.client.CompositeStateAccessor; +//import it.unimi.dsi.fastutil.objects.Object2ReferenceMap; +//import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +//import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +//import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; +//import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +//import net.fabricmc.fabric.api.client.rendering.v1.level.LevelTerrainRenderContext; +//import net.minecraft.client.Minecraft; +//import net.minecraft.client.renderer.LevelRenderer; +//import net.minecraft.client.renderer.MultiBufferSource; +//import net.minecraft.client.renderer.RenderPipelines; +//import net.minecraft.client.renderer.RenderType; +//import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +//import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +//import net.minecraft.client.renderer.chunk.SectionBuffers; +//import net.minecraft.client.renderer.fog.FogRenderer; +//import net.minecraft.client.renderer.texture.OverlayTexture; +//import net.minecraft.core.BlockPos; +//import net.minecraft.util.profiling.Profiler; +//import net.minecraft.util.profiling.ProfilerFiller; +//import net.minecraft.world.level.block.entity.BlockEntity; +//import net.minecraft.world.phys.Vec3; +//import org.jetbrains.annotations.NotNull; +//import org.joml.Vector4f; +//import org.slf4j.Logger; +// +//import java.nio.ByteBuffer; +//import java.util.*; +// +//public abstract class BakedBlockEntityRenderer implements BlockEntityRenderer { +// protected final BlockEntityRendererProvider.Context context; +// +// protected BakedBlockEntityRenderer(BlockEntityRendererProvider.Context context) { +// this.context = context; +// } +// +// /** +// * Handles invalidation and passing of rendered vertices to the baking system. +// * Override {@link #renderBaked(BlockEntity, PoseStack, MultiBufferSource, int, int)} and +// * {@link #renderBaked(BlockEntity, PoseStack, MultiBufferSource, int, int)} instead of this method. +// */ +// @Override +// public final void render(T entity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, Vec3 cameraPos) { +// renderUnbaked(entity, tickDelta, matrices, vertexConsumers, light, overlay, cameraPos); +// Manager.activateRegion(entity.getBlockPos()); +// } +// +// /** +// * Render vertices to be baked into the render region. This method will be called every time the render region is rebuilt - so +// * you should only render vertices that don't move here. You can call {@link Manager#markForRebuild(BlockPos)} to +// * cause the render region to be rebuilt, but do not call this too frequently as it will affect performance. +// * You must use the provided VertexConsumerProvider and MatrixStack to render your vertices - any use of Tessellator +// * or RenderSystem here will not work. If you need custom rendering settings, you can use a custom RenderLayer. +// */ +// public abstract void renderBaked(T entity, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay); +// +// /** +// * Render vertices immediately. This works exactly the same way as a normal BER render method, and can be used for dynamic +// * rendering that changes every frame. In this method you can also check for render invalidation and call {@link Manager#markForRebuild(BlockPos)} +// * as appropriate. +// */ +// public abstract void renderUnbaked(T entity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, Vec3 cameraPos); +// +// public abstract boolean shouldBake(T entity); +// +// private record RenderRegionPos(int x, int z, @NotNull BlockPos origin) { +// public RenderRegionPos(int x, int z) { +// this(x, z, new BlockPos(x << Manager.REGION_SHIFT, 0, z << Manager.REGION_SHIFT)); +// } +// +// public RenderRegionPos(BlockPos pos) { +// this(pos.getX() >> Manager.REGION_SHIFT, pos.getZ() >> Manager.REGION_SHIFT); +// } +// +// @Override +// public boolean equals(Object o) { +// if (this == o) return true; +// if (o == null || getClass() != o.getClass()) return false; +// +// RenderRegionPos that = (RenderRegionPos) o; +// return x == that.x && +// z == that.z; +// } +// +// @Override +// public int hashCode() { +// return Objects.hash(x, z); +// } +// } +// +// public static class Manager { +// // 2x2 chunks size for regions +// public static final int REGION_FROMCHUNK_SHIFT = 1; +// public static final int REGION_SHIFT = 4 + REGION_FROMCHUNK_SHIFT; +// public static final int MAX_XZ_IN_REGION = (16 << REGION_FROMCHUNK_SHIFT) - 1; +// public static final int VIEW_RADIUS = 3; +// +// private static final Object2ReferenceMap regions = new Object2ReferenceOpenHashMap<>(); +// private static final Set needsRebuild = Sets.newHashSet(); +// +// private static class CachedVertexConsumerProvider implements MultiBufferSource { +// private final Reference2ReferenceMap allocators = new Reference2ReferenceOpenHashMap<>(); +// private final Reference2ReferenceMap builders = new Reference2ReferenceOpenHashMap<>(); +// +// @Override +// public VertexConsumer getBuffer(RenderType layer) { +// return builders.computeIfAbsent(layer, l1 -> new BufferBuilder( +// allocators.computeIfAbsent(layer, l2 -> new ByteBufferBuilder(layer.bufferSize())), +// layer.mode(), +// layer.format())); +// } +// +// /** +// * Resets the provider so another scene can be rendered +// */ +// public void reset() { +// allocators.forEach((layer, allocator) -> allocator.discard()); +// builders.clear(); +// } +// } +// +// private static final CachedVertexConsumerProvider vcp = new CachedVertexConsumerProvider(); +// +// private static final Logger LOGGER = LogUtils.getLogger(); +// +// private static class RegionBuffer { +// private final Map layerBuffers = new Reference2ReferenceOpenHashMap<>(); +// private final Set uploadedLayers = new ObjectOpenHashSet<>(); +// +// @SuppressWarnings("DataFlowIssue") +// public void render(RenderType layer, PoseStack matrices) { +// RenderTarget framebuffer; +// if (layer instanceof RenderType.CompositeRenderType) { +// framebuffer = ((CompositeStateAccessor) (Object) ((CompositeRenderTypeAccessor) layer).getPhases()).getTarget().getRenderTarget(); +// } else { +// framebuffer = Minecraft.getInstance().getMainRenderTarget(); +// } +// +// RenderPipeline pipeline; +// if (layer instanceof RenderType.CompositeRenderType) { +// pipeline = ((CompositeRenderTypeAccessor) layer).getPipeline(); +// } else { +// pipeline = RenderPipelines.SOLID; +// } +// +// layer.setupRenderState(); +// GpuBufferSlice gpuBufferSlice = RenderSystem.getDynamicUniforms() +// .writeTransform( +// matrices.last().pose(), +// new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), +// RenderSystem.getModelOffset(), +// RenderSystem.getTextureMatrix(), +// RenderSystem.getShaderLineWidth() +// ); +// +// try (RenderPass renderPass = RenderSystem.getDevice() +// .createCommandEncoder() +// .createRenderPass( +// () -> "Glowcase baked BER section layers", +// framebuffer.getColorTextureView(), +// OptionalInt.empty(), +// framebuffer.getDepthTextureView(), +// OptionalDouble.empty() +// )) { +// SectionBuffers buffers = layerBuffers.get(layer); +// +// GpuBuffer indexBuffer; +// VertexFormat.IndexType indexType; +// if (buffers.getIndexBuffer() == null) { +// RenderSystem.AutoStorageIndexBuffer shapeIndexBuffer = RenderSystem.getSequentialBuffer(layer.mode()); +// indexBuffer = shapeIndexBuffer.getBuffer(buffers.getIndexCount()); +// indexType = shapeIndexBuffer.type(); +// } else { +// indexBuffer = buffers.getIndexBuffer(); +// indexType = buffers.getIndexType(); +// } +// +// ScissorState scissorState = RenderSystem.getScissorStateForRenderTypeDraws(); +// if (scissorState.enabled()) { +// renderPass.enableScissor(scissorState.x(), scissorState.y(), scissorState.width(), scissorState.height()); +// } +// +// for (int j = 0; j < 12; j++) { +// GpuTextureView gpuTextureView3 = RenderSystem.getShaderTexture(j); +// if (gpuTextureView3 != null) { +// renderPass.bindSampler("Sampler" + j, gpuTextureView3); +// } +// } +// +// renderPass.setPipeline(pipeline); +// renderPass.setUniform("DynamicTransforms", gpuBufferSlice); +// renderPass.setVertexBuffer(0, buffers.getVertexBuffer()); +// renderPass.setIndexBuffer(indexBuffer, indexType); +// RenderSystem.bindDefaultUniforms(renderPass); +// +// renderPass.drawIndexed(0, 0, buffers.getIndexCount(), 1); +// } +// layer.clearRenderState(); +// +// //VertexBuffer buf = layerBuffers.get(layer); +// //buf.bind(); +// //layer.startDrawing(); +// //buf.draw(matrices.peek().getPositionMatrix(), projectionMatrix, RenderSystem.getShader()); +// //layer.endDrawing(); +// //VertexBuffer.unbind(); +// } +// +// public void upload(RenderType layer, BufferBuilder newBuf) { +// try (MeshData buffer = newBuf.build()) { +// if (buffer == null) return; +// +// CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder(); +// SectionBuffers oldBuffers = this.layerBuffers.get(layer); +// if (oldBuffers != null) { +// if (oldBuffers.getVertexBuffer().size() < buffer.vertexBuffer().remaining()) { +// oldBuffers.getVertexBuffer().close(); +// oldBuffers.setVertexBuffer( +// RenderSystem.getDevice() +// .createBuffer( +// () -> "Glowcase Region vertex buffer - layer: " + layer.getName(), +// GpuBuffer.USAGE_VERTEX | GpuBuffer.USAGE_COPY_DST, +// buffer.vertexBuffer() +// ) +// ); +// } else if (!oldBuffers.getVertexBuffer().isClosed()) { +// commandEncoder.writeToBuffer(oldBuffers.getVertexBuffer().slice(), buffer.vertexBuffer()); +// } +// +// ByteBuffer byteBuffer = buffer.indexBuffer(); +// if (byteBuffer != null) { +// if (oldBuffers.getIndexBuffer() != null && oldBuffers.getIndexBuffer().size() >= byteBuffer.remaining()) { +// if (!oldBuffers.getIndexBuffer().isClosed()) { +// commandEncoder.writeToBuffer(oldBuffers.getIndexBuffer().slice(), byteBuffer); +// } +// } else { +// if (oldBuffers.getIndexBuffer() != null) { +// oldBuffers.getIndexBuffer().close(); +// } +// +// oldBuffers.setIndexBuffer( +// RenderSystem.getDevice() +// .createBuffer( +// () -> "Glowcase Region index buffer - layer: " + layer.getName(), +// GpuBuffer.USAGE_INDEX | GpuBuffer.USAGE_COPY_DST, +// byteBuffer +// ) +// ); +// } +// } else if (oldBuffers.getIndexBuffer() != null) { +// oldBuffers.getIndexBuffer().close(); +// oldBuffers.setIndexBuffer(null); +// } +// +// oldBuffers.setIndexCount(buffer.drawState().indexCount()); +// oldBuffers.setIndexType(buffer.drawState().indexType()); +// } else { +// GpuBuffer vertexBuffer = RenderSystem.getDevice() +// .createBuffer( +// () -> "Glowcase Region vertex buffer - layer: " + layer.getName(), +// GpuBuffer.USAGE_VERTEX | GpuBuffer.USAGE_COPY_DST, +// buffer.vertexBuffer() +// ); +// ByteBuffer sortedBuffer = buffer.indexBuffer(); +// GpuBuffer indexBuffer = sortedBuffer != null +// ? RenderSystem.getDevice() +// .createBuffer( +// () -> "Glowcase Region index buffer - layer: " + layer.getName(), +// GpuBuffer.USAGE_INDEX | GpuBuffer.USAGE_COPY_DST, +// sortedBuffer +// ) +// : null; +// this.layerBuffers.put(layer, new SectionBuffers(vertexBuffer, indexBuffer, buffer.drawState().indexCount(), buffer.drawState().indexType())); +// } +// +// this.uploadedLayers.add(layer); +// } +// } +// +// public void reset() { +// layerBuffers.values().forEach(SectionBuffers::close); +// layerBuffers.clear(); +// uploadedLayers.clear(); +// } +// } +// +// /** +// * Causes the render region containing this BlockEntity to be rebuilt - +// * do not call this too frequently as it will affect performance. +// * An invalidation will not immediately cause the next frame to contain an updated view (and call to renderBaked) +// * as all render region rebuilds must call every BER that is to be rendered, otherwise they will be missing from the +// * vertex buffer. +// */ +// public static void markForRebuild(BlockPos pos) { +// needsRebuild.add(new RenderRegionPos(pos)); +// } +// +// // TODO: move chunk baking off-thread? +// +// private static boolean isVisiblePos(RenderRegionPos rrp, Vec3 cam) { +// return Math.abs(rrp.x - ((int) cam.x() >> REGION_SHIFT)) <= VIEW_RADIUS && Math.abs(rrp.z - ((int) cam.z() >> REGION_SHIFT)) <= VIEW_RADIUS; +// } +// +// @SuppressWarnings("unchecked") +// public static void render(LevelTerrainRenderContext wrc) { +// ProfilerFiller profiler = Profiler.get(); +// profiler.push("glowcase:baked_block_entity_rendering"); +// +// Vec3 cam = wrc.camera().getPosition(); +// +// if (!needsRebuild.isEmpty()) { +// profiler.push("rebuild"); +// +// // Make builders for regions that are marked for rebuild, render and upload to RegionBuffers +// Set removing = Sets.newHashSet(); +// List blockEntities = new ArrayList<>(); +// PoseStack bakeMatrices = new PoseStack(); +// for (RenderRegionPos rrp : needsRebuild) { +// if (isVisiblePos(rrp, cam)) { +// // For the current region, rebuild each render layer using the buffer builders +// // Find all block entities in this region +// for (int chunkX = rrp.x << REGION_FROMCHUNK_SHIFT; chunkX < (rrp.x + 1) << REGION_FROMCHUNK_SHIFT; chunkX++) { +// for (int chunkZ = rrp.z << REGION_FROMCHUNK_SHIFT; chunkZ < (rrp.z + 1) << REGION_FROMCHUNK_SHIFT; chunkZ++) { +// blockEntities.addAll(wrc.world().getChunk(chunkX, chunkZ).getBlockEntities().values()); +// } +// } +// +// if (!blockEntities.isEmpty()) { +// boolean bakedAnything = false; +// +// for (BlockEntity be : blockEntities) { +// if (Minecraft.getInstance().getBlockEntityRenderDispatcher().getRenderer(be) instanceof BakedBlockEntityRenderer renderer && renderer.shouldBake(be)) { +// BlockPos pos = be.getBlockPos(); +// bakeMatrices.pushPose(); +// bakeMatrices.translate(pos.getX() & MAX_XZ_IN_REGION, pos.getY(), pos.getZ() & MAX_XZ_IN_REGION); +// try { +// renderer.renderBaked(be, bakeMatrices, vcp, LevelRenderer.getLightColor(wrc.world(), pos), OverlayTexture.NO_OVERLAY); +// bakedAnything = true; +// } catch (Throwable t) { +// LOGGER.error("Block entity renderer threw exception during baking: ", t); +// } +// bakeMatrices.popPose(); +// } +// } +// +// blockEntities.clear(); +// +// if (bakedAnything) { +// RegionBuffer buf = regions.computeIfAbsent(rrp, k -> new RegionBuffer()); +// buf.reset(); +// vcp.builders.forEach(buf::upload); +// vcp.reset(); +// } else { +// removing.add(rrp); +// } +// } else { +// removing.add(rrp); +// } +// } +// } +// // We've processed all pending rebuilds now +// needsRebuild.clear(); +// // These regions no longer contain anything +// removing.forEach(rrp -> { +// RegionBuffer buf = regions.get(rrp); +// if (buf != null) { +// buf.reset(); +// regions.remove(rrp, buf); +// } +// }); +// +// profiler.pop(); +// } +// +// if (!regions.isEmpty()) { +// profiler.push("render"); +// +// /* +// * Set the fog end to an extremely high value, this is a total hack but. +// * It's needed to make fog not bleed into text blocks +// */ +// GpuBufferSlice originalFog = RenderSystem.getShaderFog(); +// RenderSystem.setShaderFog(((GameRendererAccessor) wrc.gameRenderer()).getFogRenderer().getBuffer(FogRenderer.FogMode.NONE)); +// // Iterate over all RegionBuffers, render visible and remove non-visible RegionBuffers +// PoseStack matrices = wrc.matrixStack(); +// matrices.pushPose(); +// matrices.mulPose(wrc.positionMatrix()); +// matrices.translate(-cam.x, -cam.y, -cam.z); +// var iter = regions.object2ReferenceEntrySet().iterator(); +// while (iter.hasNext()) { +// var entry = iter.next(); +// RenderRegionPos rrp = entry.getKey(); +// RegionBuffer regionBuffer = entry.getValue(); +// if (isVisiblePos(entry.getKey(), cam)) { +// // Iterate over used render layers in the region, render them +// matrices.pushPose(); +// matrices.translate(rrp.origin.getX(), rrp.origin.getY(), rrp.origin.getZ()); +// for (RenderType l : regionBuffer.uploadedLayers) { +// regionBuffer.render(l, matrices); +// } +// matrices.popPose(); +// } else { +// regionBuffer.reset(); +// iter.remove(); +// } +// } +// RenderSystem.setShaderFog(originalFog); +// matrices.popPose(); +// +// profiler.pop(); +// } +// +// //RenderSystem.setShaderColor(1, 1, 1, 1); +// +// profiler.pop(); +// } +// +// public static void activateRegion(BlockPos pos) { +// RenderRegionPos rrp = new RenderRegionPos(pos); +// if (!regions.containsKey(rrp)) { +// markForRebuild(pos); +// } +// } +// +// public static void reset() { +// regions.values().forEach(RegionBuffer::reset); +// regions.clear(); +// needsRebuild.clear(); +// } +// } +//} diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ConfigLinkBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ConfigLinkBlockEntityRenderer.java index ad218a54..403e206a 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ConfigLinkBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ConfigLinkBlockEntityRenderer.java @@ -1,45 +1,66 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ConfigLinkBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.Camera; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font.DisplayMode; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; public record ConfigLinkBlockEntityRenderer( - BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/config_link_block.png"); - public void render(ConfigLinkBlockEntity entity, float f, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - Camera camera = context.getRenderDispatcher().camera; - BlockEntityRenderUtil.renderBillboardPlaceholder(entity, ITEM_TEXTURE, 0.5F, matrices, vertexConsumers, camera); - - matrices.push(); - if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult bhr && bhr.getBlockPos().equals(entity.getPos())) { - matrices.translate(0.5D, 0.5D, 0.5D); - matrices.scale(0.5F, 0.5F, 0.5F); - float n = -camera.getYaw(); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(n)); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(camera.getPitch())); + public static class ConfigLinkRenderState extends BlockEntityRenderState { + public FormattedCharSequence text = FormattedCharSequence.EMPTY; + } + + @Override + public ConfigLinkRenderState createRenderState() { + return new ConfigLinkRenderState(); + } + + @Override + public void extractRenderState(ConfigLinkBlockEntity blockEntity, ConfigLinkRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + state.text = Component.literal(blockEntity.getText()).getVisualOrderText(); + } + + @Override + public void submit(ConfigLinkRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + BlockEntityRenderUtil.renderBillboardPlaceholder(state, ITEM_TEXTURE, 0.5F, poseStack, submitNodeCollector, camera); + + poseStack.pushPose(); + if (Minecraft.getInstance().hitResult instanceof BlockHitResult bhr // + && bhr.getBlockPos().equals(state.blockPos)) { + poseStack.translate(0.5D, 0.5D, 0.5D); + poseStack.scale(0.5F, 0.5F, 0.5F); + float n = -camera.yRot; + poseStack.mulPose(Axis.YP.rotationDegrees(n)); + poseStack.mulPose(Axis.XP.rotationDegrees(camera.xRot)); float scale = 0.025F; - matrices.scale(scale, scale, scale); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180)); - matrices.translate(-context.getTextRenderer().getWidth(entity.getText()) / 2F, -4, -scale); + poseStack.scale(scale, scale, scale); + poseStack.mulPose(Axis.ZP.rotationDegrees(180)); + poseStack.translate(-context.font().width(state.text) / 2F, -4, -scale); // Fixes shadow being rendered in front of actual text - matrices.scale(1, 1, -1); - context.getTextRenderer().draw(entity.getText(), 0, 0, 0xFFFFFF, true, matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); + poseStack.scale(1, 1, -1); + + submitNodeCollector.submitText(poseStack, 0, 0, state.text, true, DisplayMode.NORMAL, 0xFF, 0xFFFFFFFF, 0, 0); } - matrices.pop(); + poseStack.popPose(); } + } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/EntityDisplayBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/EntityDisplayBlockEntityRenderer.java index a5777339..13d506ea 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/EntityDisplayBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/EntityDisplayBlockEntityRenderer.java @@ -1,44 +1,63 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.EntityDisplayBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -public record EntityDisplayBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.state.EntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.resources.Identifier; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; + +public record EntityDisplayBlockEntityRenderer(BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/entity_display_block.png"); + public static class EntityDisplayRenderState extends BlockEntityRenderState {} + + @Override + public EntityDisplayRenderState createRenderState() { + return new EntityDisplayRenderState(); + } + @Override - public void render(EntityDisplayBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - - matrices.push(); - matrices.translate(0.5D, 0D, 0.5D); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.getYaw())); - matrices.translate(entity.getOffset().x(), entity.getOffset().y(), entity.getOffset().z()); - matrices.scale(entity.getScale().x(), entity.getScale().y(), entity.getScale().z()); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(entity.getPitch())); - Entity renderEntity = entity.getDisplayEntity(); - if (renderEntity != null) { - //noinspection unchecked - EntityRenderer entityRenderer = (EntityRenderer) context.getEntityRenderDispatcher().getRenderer(renderEntity); - EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(renderEntity, 0); - entityRenderer.render(entityRenderState, matrices, vertexConsumers, light); - } - - matrices.pop(); - - if (entity.matchesStack(ItemStack.EMPTY) || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos())) BlockEntityRenderUtil.renderCenteredPlaceholder(entity, ITEM_TEXTURE, 1.0F, RotationAxis.POSITIVE_Y.rotationDegrees(entity.getYaw()), matrices, vertexConsumers); + public void extractRenderState(EntityDisplayBlockEntity blockEntity, EntityDisplayRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); } + + @Override + public void submit(EntityDisplayRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { +// FIXME update to 26.1 + // if (entity.getLevel() == null || entity.getLevel().getBlockState(entity.getBlockPos()).isAir()) return; +// +// matrices.pushPose(); +// matrices.translate(0.5D, 0D, 0.5D); +// matrices.mulPose(Axis.YP.rotationDegrees(entity.getYaw())); +// matrices.translate(entity.getOffset().x(), entity.getOffset().y(), entity.getOffset().z()); +// matrices.scale(entity.getScale().x(), entity.getScale().y(), entity.getScale().z()); +// matrices.mulPose(Axis.XP.rotationDegrees(entity.getPitch())); +// Entity renderEntity = entity.getDisplayEntity(); +// if (renderEntity != null) { +// //noinspection unchecked +// EntityRenderer entityRenderer = (EntityRenderer) context.getEntityRenderer().getRenderer(renderEntity); +// EntityRenderState entityRenderState = entityRenderer.createRenderState(renderEntity, 0); +// entityRenderer.render(entityRenderState, matrices, vertexConsumers, light); +// } +// +// matrices.popPose(); +// +// if (entity.matchesStack(ItemStack.EMPTY) || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getBlockPos())) BlockEntityRenderUtil.renderCenteredPlaceholder(entity, ITEM_TEXTURE, 1.0F, Axis.YP.rotationDegrees(entity.getYaw()), matrices, vertexConsumers); + + } + } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/HyperlinkBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/HyperlinkBlockEntityRenderer.java index c9bc1091..6b08d758 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/HyperlinkBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/HyperlinkBlockEntityRenderer.java @@ -1,52 +1,71 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.Camera; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -public record HyperlinkBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font.DisplayMode; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; + +public record HyperlinkBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/hyperlink_block.png"); - public void render(HyperlinkBlockEntity entity, float f, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - Camera camera = context.getRenderDispatcher().camera; - BlockEntityRenderUtil.renderBillboardPlaceholder(entity, ITEM_TEXTURE, 0.5F, matrices, vertexConsumers, camera); - Text title; - if (entity.getUrl().isBlank()) { - title = Text.translatable("gui.glowcase.warning.no_content").formatted(Formatting.RED); + public static class HyperlinkRenderState extends BlockEntityRenderState { + public FormattedCharSequence title = FormattedCharSequence.EMPTY; + } + + @Override + public HyperlinkRenderState createRenderState() { + return new HyperlinkRenderState(); + } + + @Override + public void extractRenderState(HyperlinkBlockEntity blockEntity, HyperlinkRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + if (blockEntity.getUrl().isBlank()) { + state.title = Component.translatable("gui.glowcase.warning.no_content").withStyle(ChatFormatting.RED).getVisualOrderText(); } else { - title = Text.literal(entity.getText()); + state.title = Component.literal(blockEntity.getText()).getVisualOrderText(); } + } + + @Override + public void submit(HyperlinkRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + BlockEntityRenderUtil.renderBillboardPlaceholder(state, ITEM_TEXTURE, 0.5F, poseStack, submitNodeCollector, camera); - matrices.push(); - if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult bhr && bhr.getBlockPos().equals(entity.getPos())) { - matrices.translate(0.5D, 0.5D, 0.5D); - matrices.scale(0.5F, 0.5F, 0.5F); - float n = -camera.getYaw(); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(n)); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(camera.getPitch())); + poseStack.pushPose(); + if (Minecraft.getInstance().hitResult instanceof BlockHitResult bhr && bhr.getBlockPos().equals(state.blockPos)) { + poseStack.translate(0.5D, 0.5D, 0.5D); + poseStack.scale(0.5F, 0.5F, 0.5F); + float n = -camera.yRot; + poseStack.mulPose(Axis.YP.rotationDegrees(n)); + poseStack.mulPose(Axis.XP.rotationDegrees(camera.xRot)); float scale = 0.025F; - matrices.scale(scale, scale, scale); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180)); - matrices.translate(-context.getTextRenderer().getWidth(title) / 2F, -4, -scale); + poseStack.scale(scale, scale, scale); + poseStack.mulPose(Axis.ZP.rotationDegrees(180)); + poseStack.translate(-context.font().width(state.title) / 2F, -4, -scale); // Fixes shadow being rendered in front of actual text - matrices.scale(1, 1, -1); - context.getTextRenderer().draw(title, 0, 0, 0xFFFFFFFF, true, matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); + poseStack.scale(1, 1, -1); + + submitNodeCollector.submitText(poseStack, 0, 0, state.title, true, DisplayMode.NORMAL, 0xFF, 0xFFFFFFFF, 0x00000000, 0); } - matrices.pop(); + poseStack.popPose(); } + } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemAcceptorBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemAcceptorBlockEntityRenderer.java index 006de6ee..1863b485 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemAcceptorBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemAcceptorBlockEntityRenderer.java @@ -1,84 +1,94 @@ package dev.hephaestus.glowcase.client.render.block.entity; import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.systems.RenderSystem; -import dev.hephaestus.glowcase.Glowcase; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.block.ItemAcceptorBlock; import dev.hephaestus.glowcase.block.entity.ItemAcceptorBlockEntity; -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.render.item.ItemRenderer; -import net.minecraft.client.render.item.KeyedItemRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.util.Colors; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.phys.Vec3; import org.joml.Matrix4f; import org.joml.Quaternionf; +import org.jspecify.annotations.Nullable; -public record ItemAcceptorBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { - private static final Quaternionf ITEM_LIGHT_ROTATION_3D = RotationAxis.POSITIVE_X.rotationDegrees(-15).mul(RotationAxis.POSITIVE_Y.rotationDegrees(15)); - private static final Quaternionf ITEM_LIGHT_ROTATION_FLAT = RotationAxis.POSITIVE_X.rotationDegrees(-45); +public record ItemAcceptorBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { + private static final Quaternionf ITEM_LIGHT_ROTATION_3D = Axis.XP.rotationDegrees(-15).mul(Axis.YP.rotationDegrees(15)); + private static final Quaternionf ITEM_LIGHT_ROTATION_FLAT = Axis.XP.rotationDegrees(-45); + + public static class ItemAcceptorRenderState extends BlockEntityRenderState { + public ItemStackRenderState itemRenderState = new ItemStackRenderState(); + public int count; + public float rotation; + } @Override - public void render(ItemAcceptorBlockEntity entity, float tickProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - MinecraftClient client = MinecraftClient.getInstance(); + public ItemAcceptorRenderState createRenderState() { + return new ItemAcceptorRenderState(); + } - ItemRenderer itemRenderer = context.getItemRenderer(); - KeyedItemRenderState renderState = new KeyedItemRenderState(); - client.getItemModelManager().clearAndUpdate(renderState, entity.getDisplayItemStack(), ItemDisplayContext.GUI, entity.getWorld(), null, 0); + @Override + public void extractRenderState(ItemAcceptorBlockEntity blockEntity, ItemAcceptorRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + state.count = blockEntity.count; + this.context.itemModelResolver().updateForTopItem(state.itemRenderState, blockEntity.getDisplayItemStack(), ItemDisplayContext.GUI, blockEntity.getLevel(), null, (int) state.blockPos.asLong()); + state.rotation = getRotationYForSide2D(blockEntity.getBlockState().getValue(ItemAcceptorBlock.FACING)); + } + + @Override + public void submit(ItemAcceptorRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + Minecraft client = Minecraft.getInstance(); // Render item - float yaw = 0; - matrices.push(); - matrices.translate(0.5, 0.5, 0.5); - BlockState blockState = entity.getWorld().getBlockState(entity.getPos()); - if (blockState.isOf(Glowcase.ITEM_ACCEPTOR_BLOCK.get())) { - yaw = getRotationYForSide2D(blockState.get(ItemAcceptorBlock.FACING)); - } - matrices.peek().getPositionMatrix().mul(new Matrix4f().rotateY(yaw).translate(-0.125f, 0.125f, 0.51F).scale(1, 1, 0.01F)); - matrices.scale(0.5F, 0.5F, 0.5F); + poseStack.pushPose(); + poseStack.translate(0.5, 0.5, 0.5); + + poseStack.mulPose(new Matrix4f().rotateY(state.rotation).translate(-0.125f, 0.125f, 0.51F).scale(1, 1, 0.01F)); + poseStack.scale(0.5F, 0.5F, 0.5F); GpuBufferSlice shaderLights = RenderSystem.getShaderLights(); - if (renderState.isSideLit()) { - matrices.peek().getNormalMatrix().rotate(ITEM_LIGHT_ROTATION_3D); - client.gameRenderer.getDiffuseLighting().setShaderLights(DiffuseLighting.Type.ITEMS_3D); + if (state.itemRenderState.usesBlockLight()) { + poseStack.last().normal().rotate(ITEM_LIGHT_ROTATION_3D); + client.gameRenderer.getLighting().setupFor(Lighting.Entry.ITEMS_3D); } else { - matrices.peek().getNormalMatrix().rotate(ITEM_LIGHT_ROTATION_FLAT); - client.gameRenderer.getDiffuseLighting().setShaderLights(DiffuseLighting.Type.ITEMS_FLAT); + poseStack.last().normal().rotate(ITEM_LIGHT_ROTATION_FLAT); + client.gameRenderer.getLighting().setupFor(Lighting.Entry.ITEMS_FLAT); } + state.itemRenderState.submit(poseStack, submitNodeCollector, state.lightCoords, OverlayTexture.NO_OVERLAY, 0); - itemRenderer.renderItem(entity.getDisplayItemStack(), ItemDisplayContext.GUI, light, OverlayTexture.DEFAULT_UV, matrices, vertexConsumers, entity.getWorld(), 0); - - //FIXME: is this needed still? RenderSystem.setShaderLights(shaderLights); // Render count - if (entity.count > 1) { + if (state.count > 1) { float scale = 0.0625F; - matrices.translate(0, 0, 1); - matrices.scale(scale, -scale, scale); + poseStack.translate(0, 0, 1); + poseStack.scale(scale, -scale, scale); + + Font textRenderer = context.font(); + String string = String.valueOf(state.count); - TextRenderer textRenderer = context.getTextRenderer(); - String string = String.valueOf(entity.count); - textRenderer.draw(string, 9 - textRenderer.getWidth(string), 1, Colors.WHITE, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); + submitNodeCollector.submitText(poseStack, 9 - textRenderer.width(string), 1, Component.literal(string).getVisualOrderText(), true, Font.DisplayMode.NORMAL, 0xFF, 0xFFFFFFFF, 0, 0); } - matrices.pop(); + poseStack.popPose(); } private static float getRotationYForSide2D(Direction side) { - return -side.getPositiveHorizontalDegrees() * (float) Math.PI / 180f; + return -side.toYRot() * (float) Math.PI / 180f; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemDisplayBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemDisplayBlockEntityRenderer.java index d15496ae..f13ff8d8 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemDisplayBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemDisplayBlockEntityRenderer.java @@ -1,59 +1,86 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -public record ItemDisplayBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.Identifier; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import org.joml.Vector3f; +import org.jspecify.annotations.Nullable; + +public record ItemDisplayBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/item_display_block.png"); - @Override - public void render(ItemDisplayBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; + public static class ItemDisplayRenderState extends BlockEntityRenderState { + public ItemStackRenderState itemRenderState = new ItemStackRenderState(); + public boolean renderAsBlock; + public boolean shouldRenderPlaceholder; + public float yaw; + public float pitch; + public Vector3f offset = new Vector3f(0, 0, 0); + public Vector3f scale = new Vector3f(0, 0, 0); + } - boolean renderAsBlock = entity.getRenderAsBlock(); - matrices.push(); - - if (renderAsBlock && entity.getStack().getItem() instanceof BlockItem blockItem) { - matrices.translate(0.5D, 0.5D, 0.5D); + @Override + public ItemDisplayRenderState createRenderState() { + return new ItemDisplayRenderState(); + } - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180.0F + entity.getYaw())); - matrices.translate(entity.getOffset().x(), entity.getOffset().y(), entity.getOffset().z()); + @Override + public void extractRenderState(ItemDisplayBlockEntity blockEntity, ItemDisplayRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); - matrices.translate(-0.5D, -0.5D, -0.5D); + this.context.itemModelResolver().updateForTopItem(state.itemRenderState, blockEntity.getStack(), ItemDisplayContext.FIXED, blockEntity.getLevel(), null, (int) state.blockPos.asLong()); + state.renderAsBlock = blockEntity.getRenderAsBlock() && blockEntity.getStack().getItem() instanceof BlockItem blockItem; + state.shouldRenderPlaceholder = blockEntity.matchesStack(ItemStack.EMPTY) || BlockEntityRenderUtil.shouldRenderPlaceholder(blockEntity.getBlockPos()); + state.yaw = blockEntity.getYaw(); + state.pitch = blockEntity.getPitch(); + state.offset = blockEntity.getOffset(); + state.scale = blockEntity.getScale(); + } - matrices.scale(entity.getScale().x(), entity.getScale().y(), entity.getScale().z()); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(entity.getPitch())); + @Override + public void submit(ItemDisplayRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + poseStack.pushPose(); + poseStack.translate(0.5D, 0D, 0.5D); + poseStack.mulPose(Axis.YP.rotationDegrees(180.0F + state.yaw)); + poseStack.translate(state.offset.x(), state.offset.y(), state.offset.z()); - MinecraftClient.getInstance().getBlockRenderManager().renderBlockAsEntity(blockItem.getBlock().getDefaultState(), matrices, vertexConsumers, light, overlay); + if (state.renderAsBlock) { + // FIXME 26.1 +// poseStack.translate(-0.5D, -0.5D, -0.5D); +// +// poseStack.scale(entity.getScale().x(), entity.getScale().y(), entity.getScale().z()); +// poseStack.mulPose(Axis.XP.rotationDegrees(entity.getPitch())); +// +// Minecraft.getInstance().getBlockRenderer().renderSingleBlock(blockItem.getBlock().defaultBlockState(), poseStack, vertexConsumers, light, overlay); } else { - matrices.translate(0.5D, 0D, 0.5D); + poseStack.translate(0D, 0.5D, 0D); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180.0F + entity.getYaw())); - matrices.translate(entity.getOffset().x(), entity.getOffset().y(), entity.getOffset().z()); + poseStack.scale(state.scale.x(), state.scale.y(), state.scale.z()); + poseStack.mulPose(Axis.XP.rotationDegrees(state.pitch)); - matrices.translate(0D, 0.5D, 0D); + state.itemRenderState.submit(poseStack, submitNodeCollector, state.lightCoords, OverlayTexture.NO_OVERLAY, 0); + } - matrices.scale(entity.getScale().x(), entity.getScale().y(), entity.getScale().z()); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(entity.getPitch())); + poseStack.popPose(); - context.getItemRenderer().renderItem(entity.getStack(), ItemDisplayContext.FIXED, light, OverlayTexture.DEFAULT_UV, matrices, vertexConsumers, entity.getWorld(), 0); + if (state.shouldRenderPlaceholder) { + BlockEntityRenderUtil.renderCenteredPlaceholder(state, ITEM_TEXTURE, 1.0F, Axis.YP.rotationDegrees(state.yaw), poseStack, submitNodeCollector); } - - matrices.pop(); - - if (entity.matchesStack(ItemStack.EMPTY) || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos())) BlockEntityRenderUtil.renderCenteredPlaceholder(entity, ITEM_TEXTURE, 1.0F, RotationAxis.POSITIVE_Y.rotationDegrees(entity.getYaw()), matrices, vertexConsumers); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemProviderBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemProviderBlockEntityRenderer.java index 4a62dd98..039dfcc8 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemProviderBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ItemProviderBlockEntityRenderer.java @@ -1,47 +1,84 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.ItemProviderBlock; import dev.hephaestus.glowcase.block.entity.ItemProviderBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec2f; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.ColorHelper; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.util.ARGB; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec2; +import net.minecraft.world.phys.Vec3; import org.apache.commons.lang3.time.DurationFormatUtils; +import org.jspecify.annotations.Nullable; -public record ItemProviderBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +public record ItemProviderBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/item_provider_block.png"); + public static class ItemProviderRenderState extends BlockEntityRenderState { + public ItemStackRenderState itemRenderState = new ItemStackRenderState(); + public Direction facing = Direction.UP; + public boolean shouldRenderPlaceholder; + public boolean isBlockItem; + public boolean isInvisible; + public Component name = Component.empty(); + public int textColor; + public boolean canGive; + public Component countText; + } + @Override - public void render(ItemProviderBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - Entity camera = MinecraftClient.getInstance().getCameraEntity(); - BlockState blockState = entity.getWorld().getBlockState(entity.getPos()); + public ItemProviderRenderState createRenderState() { + return new ItemProviderRenderState(); + } + + @Override + public void extractRenderState(ItemProviderBlockEntity blockEntity, ItemProviderRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + + var stack = blockEntity.getStack(); + this.context.itemModelResolver().updateForTopItem(state.itemRenderState, stack, ItemDisplayContext.FIXED, blockEntity.getLevel(), null, (int) state.blockPos.asLong()); + state.facing = blockEntity.getBlockState().getValue(ItemProviderBlock.FACING); + state.isBlockItem = stack.getItem() instanceof BlockItem; + state.shouldRenderPlaceholder = !blockEntity.hasItem() || BlockEntityRenderUtil.shouldRenderPlaceholder(blockEntity.getBlockPos()); + state.isInvisible = blockEntity.isInvisible(); + state.name = stack.isEmpty() ? Component.translatable("gui.glowcase.none") : (Component.literal("")).append(stack.getHoverName()).withStyle(stack.getRarity().color()); + state.textColor = ARGB.opaque(state.name.getStyle().getColor() == null ? 0xFFFFFF : state.name.getStyle().getColor().getValue()); + state.canGive = blockEntity.canGiveTo(Minecraft.getInstance().player); + if (state.canGive) { + state.countText = Component.literal("%dx".formatted(blockEntity.getStack().getCount())); + } else { + long cooldownMS = blockEntity.getCooldownTicks(Minecraft.getInstance().player) * 50; + state.countText = Component.literal("[%s]".formatted(blockEntity.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED ? DurationFormatUtils.formatDuration(cooldownMS, cooldownMS > 3600000 ? "HH:mm:ss" : "mm:ss") : "MAX")).withStyle(ChatFormatting.YELLOW); + } + } - if (camera == null) return; + @Override + public void submit(ItemProviderRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + Entity cameraEntity = Minecraft.getInstance().getCameraEntity(); - matrices.push(); - matrices.translate(0.5D, 0D, 0.5D); + poseStack.pushPose(); + poseStack.translate(0.5D, 0D, 0.5D); float yaw = 0F; float pitch = 0F; @@ -49,95 +86,88 @@ public void render(ItemProviderBlockEntity entity, float tickDelta, MatrixStack boolean isBack = false; boolean isBillboard = false; - Direction facing = Direction.UP; - - if (blockState.isOf(Glowcase.ITEM_PROVIDER_BLOCK.get())) { - facing = blockState.get(ItemProviderBlock.FACING); - } - - switch (facing) { + switch (state.facing) { case DOWN, UP -> { - if (entity.getStack().getItem() instanceof BlockItem) { - Vec2f pitchAndYaw = BlockEntityRenderUtil.getTracking(camera, entity.getPos(), tickDelta); + if (state.isBlockItem) { + Vec2 pitchAndYaw = BlockEntityRenderUtil.getTracking(cameraEntity, state.blockPos, /* FIXME tickDelta */ 0); pitch = pitchAndYaw.x; yaw = pitchAndYaw.y; - matrices.multiply(RotationAxis.POSITIVE_Y.rotation(yaw)); + poseStack.mulPose(Axis.YP.rotation(yaw)); } else { - pitch = (float) Math.toRadians(camera.getPitch()); - yaw = (float) Math.toRadians(-camera.getYaw()); - matrices.multiply(RotationAxis.POSITIVE_Y.rotation(yaw)); + pitch = (float) Math.toRadians(camera.xRot); + yaw = (float) Math.toRadians(-camera.yRot); + poseStack.mulPose(Axis.YP.rotation(yaw)); isBillboard = true; } } default -> { - matrices.multiply(facing.getRotationQuaternion().mul(RotationAxis.POSITIVE_X.rotationDegrees(-90.0F))); - matrices.translate(0D, Math.sin(pitch) * -0.4, -0.4D); + poseStack.mulPose(state.facing.getRotation().mul(Axis.XP.rotationDegrees(-90.0F))); + poseStack.translate(0D, Math.sin(pitch) * -0.4, -0.4D); isBack = true; } } - matrices.translate(0, 0.5, 0); - matrices.scale(0.5F, 0.5F, 0.5F); - matrices.multiply(RotationAxis.POSITIVE_X.rotation(pitch)); + poseStack.translate(0, 0.5, 0); + poseStack.scale(0.5F, 0.5F, 0.5F); + poseStack.mulPose(Axis.XP.rotation(pitch)); - if (!entity.isInvisible()) { - matrices.push(); - if (facing.getAxis() != Direction.Axis.Y) { - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180f)); + if (!state.isInvisible) { + poseStack.pushPose(); + if (state.facing.getAxis() != Direction.Axis.Y) { + poseStack.mulPose(Axis.YP.rotationDegrees(180f)); } - context.getItemRenderer().renderItem(entity.getStack(), ItemDisplayContext.FIXED, light, OverlayTexture.DEFAULT_UV, matrices, vertexConsumers, entity.getWorld(), 0); - matrices.pop(); + state.itemRenderState.submit(poseStack, submitNodeCollector, state.lightCoords, OverlayTexture.NO_OVERLAY, 0); + + poseStack.popPose(); } - HitResult hitResult = MinecraftClient.getInstance().crosshairTarget; - if (hitResult instanceof BlockHitResult && ((BlockHitResult) hitResult).getBlockPos().equals(entity.getPos())) { - matrices.push(); - if (isBack) { // Dunno, matrices are hard - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180)); + HitResult hitResult = Minecraft.getInstance().hitResult; + if (hitResult instanceof BlockHitResult && ((BlockHitResult) hitResult).getBlockPos().equals(state.blockPos)) { + poseStack.pushPose(); + if (isBack) { // Dunno, poseStack are hard + poseStack.mulPose(Axis.XP.rotationDegrees(180)); } else { - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180)); + poseStack.mulPose(Axis.ZP.rotationDegrees(180)); } + + poseStack.translate(0, -0.6, -0.3); float scale = 0.025F; + poseStack.scale(scale, scale, scale); - matrices.translate(0, -0.6, -0.3); + Component name = state.name; + int color = ARGB.opaque(name.getStyle().getColor() == null ? 0xFFFFFF : name.getStyle().getColor().getValue()); - matrices.scale(scale, scale, scale); + poseStack.pushPose(); + poseStack.translate(-context.font().width(name) / 2F, -4, 0); + submitNodeCollector.submitText(poseStack, 0, 0, state.name.getVisualOrderText(), true, Font.DisplayMode.NORMAL, 0xFF, color, 0, 0); - ItemStack stack = entity.getStack(); - Text name = stack.isEmpty() ? Text.translatable("gui.glowcase.none") : (Text.literal("")).append(stack.getName()).formatted(stack.getRarity().getFormatting()); - int color = ColorHelper.fullAlpha(name.getStyle().getColor() == null ? 0xFFFFFF : name.getStyle().getColor().getRgb()); - matrices.push(); - matrices.translate(-context.getTextRenderer().getWidth(name) / 2F, -4, 0); - context.getTextRenderer().draw(name, 0, 0, color, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); - matrices.pop(); + poseStack.popPose(); - if (!stack.isEmpty()) { - matrices.push(); - if (entity.canGiveTo(MinecraftClient.getInstance().player)) { - Text countText = Text.literal("%dx".formatted(entity.getStack().getCount())); - matrices.translate(-context.getTextRenderer().getWidth(countText) + 16, 32, 0); - context.getTextRenderer().draw(countText, 0, 0, 0xFFFFFFFF, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); + if (!state.itemRenderState.isEmpty()) { + poseStack.pushPose(); + if (state.canGive) { + poseStack.translate(-context.font().width(state.countText) + 16, 32, 0); + submitNodeCollector.submitText(poseStack, 0, 0, state.countText.getVisualOrderText(), true, Font.DisplayMode.NORMAL, 0xFF, color, 0, 0); } else { - long cooldownMS = entity.getCooldownTicks(MinecraftClient.getInstance().player) * 50; - Text countText = Text.literal("[%s]".formatted(entity.getGivesItem() == ItemProviderBlockEntity.GivesItem.TIMED ? DurationFormatUtils.formatDuration(cooldownMS, cooldownMS > 3600000 ? "HH:mm:ss" : "mm:ss") : "MAX")).formatted(Formatting.YELLOW); - matrices.translate(-context.getTextRenderer().getWidth(countText) + 16, 24, 0); - context.getTextRenderer().draw(countText, 0, 0, 0xFFFFFFFF, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); + poseStack.translate(-context.font().width(state.countText) + 16, 24, 0); + submitNodeCollector.submitText(poseStack, 0, 0, state.countText.getVisualOrderText(), true, Font.DisplayMode.NORMAL, 0xFF, color, 0, 0); } - matrices.pop(); + poseStack.popPose(); } - matrices.pop(); + poseStack.popPose(); } - matrices.pop(); + poseStack.popPose(); + - if (!entity.hasItem() || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos())) { + if (state.shouldRenderPlaceholder) { if (isBack) { - BlockEntityRenderUtil.renderFacingPlaceholder(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers); + BlockEntityRenderUtil.renderFacingPlaceholder(state, state.facing, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector); } else if (isBillboard) { - BlockEntityRenderUtil.renderBillboardPlaceholder(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers, context.getRenderDispatcher().camera); + BlockEntityRenderUtil.renderBillboardPlaceholder(state, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector, camera); } else { - BlockEntityRenderUtil.renderTrackingPlaceholder(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers, camera, tickDelta); + BlockEntityRenderUtil.renderTrackingPlaceholder(state, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector, cameraEntity, /* FIXME tickDelta */ 0); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/OutlineBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/OutlineBlockEntityRenderer.java index 2b732c04..623de475 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/OutlineBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/OutlineBlockEntityRenderer.java @@ -1,39 +1,74 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.OutlineBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.VertexRendering; -import net.minecraft.client.render.WorldRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.render.debug.DebugRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.Vec3i; -import net.minecraft.util.shape.VoxelShapes; - -public record OutlineBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +import net.minecraft.client.renderer.ShapeRenderer; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.rendertype.RenderTypes; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.core.Vec3i; +import net.minecraft.resources.Identifier; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.Shapes; +import org.jspecify.annotations.Nullable; + +public record OutlineBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/outline_block.png"); - public void render(OutlineBlockEntity entity, float f, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - double x = entity.offset.getX(); - double y = entity.offset.getY(); - double z = entity.offset.getZ(); - double width = entity.scale.getX(); - double height = entity.scale.getY(); - double depth = entity.scale.getZ(); - - VertexRendering.drawOutline( - matrices, vertexConsumers.getBuffer(RenderLayer.getLines()), - VoxelShapes.cuboid(x, y, z, x + width, y + height, z + depth), - 0, 0, 0, entity.color | 0xFF000000 - ); - - if (entity.scale.equals(Vec3i.ZERO) || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos())) BlockEntityRenderUtil.renderBillboardPlaceholder(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers, context.getRenderDispatcher().camera); + public static class OutlineRenderState extends BlockEntityRenderState { + public boolean shouldRenderPlaceholder; + public Vec3i offset; + public Vec3i scale; + public int color; + } + + @Override + public OutlineRenderState createRenderState() { + return new OutlineRenderState(); + } + + @Override + public void extractRenderState(OutlineBlockEntity blockEntity, OutlineRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + state.shouldRenderPlaceholder = blockEntity.scale.equals(Vec3i.ZERO) || BlockEntityRenderUtil.shouldRenderPlaceholder(blockEntity.getBlockPos()); + state.offset = blockEntity.offset; + state.scale = blockEntity.scale; + state.color = blockEntity.color; + } + + @Override + public void submit(OutlineRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + if (state.shouldRenderPlaceholder) { + BlockEntityRenderUtil.renderBillboardPlaceholder(state, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector, camera); + } + + double x = state.offset.getX(); + double y = state.offset.getY(); + double z = state.offset.getZ(); + double width = state.scale.getX(); + double height = state.scale.getY(); + double depth = state.scale.getZ(); + + submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.lines(), new SubmitNodeCollector.CustomGeometryRenderer() { + @Override + public void render(PoseStack.Pose pose, VertexConsumer buffer) { + poseStack.pushPose(); + poseStack.mulPose(pose.pose()); + ShapeRenderer.renderShape( + poseStack, buffer, + Shapes.box(x, y, z, x + width, y + height, z + depth), + 0, 0, 0, state.color | 0xFF000000, 1 + ); + poseStack.popPose(); + } + }); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ParticleDisplayBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ParticleDisplayBlockEntityRenderer.java index ae9d3e20..20b53922 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ParticleDisplayBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ParticleDisplayBlockEntityRenderer.java @@ -1,23 +1,43 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ParticleDisplayBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; import dev.hephaestus.glowcase.util.DeviatedInteger; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.Vec3d; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.resources.Identifier; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; -public record ParticleDisplayBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +public record ParticleDisplayBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/particle_display.png"); - public void render(ParticleDisplayBlockEntity entity, float f, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - if (entity.count.equals(DeviatedInteger.ZERO) || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos(), false)) { - BlockEntityRenderUtil.renderBillboardPlaceholder(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers, context.getRenderDispatcher().camera); + public static class ParticleDisplayRenderState extends BlockEntityRenderState { + public boolean shouldRenderPlaceholder; + } + + @Override + public ParticleDisplayRenderState createRenderState() { + return new ParticleDisplayRenderState(); + } + + @Override + public void extractRenderState(ParticleDisplayBlockEntity blockEntity, ParticleDisplayRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + state.shouldRenderPlaceholder = blockEntity.count.equals(DeviatedInteger.ZERO) || BlockEntityRenderUtil.shouldRenderPlaceholder(state.blockPos, false); + } + + @Override + public void submit(ParticleDisplayRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + if (state.shouldRenderPlaceholder) { + BlockEntityRenderUtil.renderBillboardPlaceholder(state, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector, camera); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/PopupBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/PopupBlockEntityRenderer.java index 39cab6c6..a848fe10 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/PopupBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/PopupBlockEntityRenderer.java @@ -1,54 +1,71 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.PopupBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.Camera; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.PlainTextContent; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font.DisplayMode; +import net.minecraft.client.renderer.Lightmap; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.contents.PlainTextContents; +import net.minecraft.resources.Identifier; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; -public record PopupBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +public record PopupBlockEntityRenderer(BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/popup_block.png"); - public void render(PopupBlockEntity entity, float f, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - Camera camera = context.getRenderDispatcher().camera; - BlockEntityRenderUtil.renderBillboardPlaceholder(entity, ITEM_TEXTURE, 0.5F, matrices, vertexConsumers, camera); + public static class PopupRenderState extends BlockEntityRenderState { + public Component title; + } + + @Override + public PopupBlockEntityRenderer.PopupRenderState createRenderState() { + return new PopupBlockEntityRenderer.PopupRenderState(); + } + + @Override + public void extractRenderState(PopupBlockEntity blockEntity, PopupRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + if (blockEntity.lines.size() == 1 && blockEntity.lines.getFirst().getContents().equals(PlainTextContents.EMPTY)) { + state.title = Component.translatable("gui.glowcase.warning.no_content").withStyle(ChatFormatting.RED); + } else { + state.title = Component.literal(blockEntity.title); + } + } - matrices.push(); - if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult bhr && bhr.getBlockPos().equals(entity.getPos())) { - Text title; - if (entity.lines.size() == 1 && entity.lines.getFirst().getContent().equals(PlainTextContent.EMPTY)) { - title = Text.translatable("gui.glowcase.warning.no_content").formatted(Formatting.RED); - } else { - title = Text.literal(entity.title); - } + @Override + public void submit(PopupBlockEntityRenderer.PopupRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + BlockEntityRenderUtil.renderBillboardPlaceholder(state, ITEM_TEXTURE, 0.5F, poseStack, submitNodeCollector, camera); - matrices.translate(0.5D, 0.5D, 0.5D); - matrices.scale(0.5F, 0.5F, 0.5F); - float n = -camera.getYaw(); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(n)); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(camera.getPitch())); + poseStack.pushPose(); + if (Minecraft.getInstance().hitResult instanceof BlockHitResult bhr && bhr.getBlockPos().equals(state.blockPos)) { + poseStack.translate(0.5D, 0.5D, 0.5D); + poseStack.scale(0.5F, 0.5F, 0.5F); + float n = -camera.yRot; + poseStack.mulPose(Axis.YP.rotationDegrees(n)); + poseStack.mulPose(Axis.XP.rotationDegrees(camera.xRot)); float scale = 0.025F; - matrices.scale(scale, scale, scale); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180)); - matrices.translate(-context.getTextRenderer().getWidth(title) / 2F, -4, -scale); + poseStack.scale(scale, scale, scale); + poseStack.mulPose(Axis.ZP.rotationDegrees(180)); + poseStack.translate(-context.font().width(state.title) / 2F, -4, -scale); // Fixes shadow being rendered in front of actual text - matrices.scale(1, 1, -1); - context.getTextRenderer().draw(title, 0, 0, 0xFFFFFFFF, true, matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); + poseStack.scale(1, 1, -1); + submitNodeCollector.submitText(poseStack, 0, 0, state.title.getVisualOrderText(), true, DisplayMode.NORMAL, state.lightCoords, 0xFFFFFFFF, 0, 0); } - matrices.pop(); + poseStack.popPose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/RecipeBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/RecipeBlockEntityRenderer.java index fe8ae5df..c4d04736 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/RecipeBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/RecipeBlockEntityRenderer.java @@ -1,73 +1,92 @@ package dev.hephaestus.glowcase.client.render.block.entity; -import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import dev.hephaestus.glowcase.client.GlowcaseClient; - +import com.mojang.blaze3d.vertex.PoseStack; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.RecipeBlockEntity; +import dev.hephaestus.glowcase.block.entity.TextBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import dev.hephaestus.glowcase.client.util.EmiWorldRenderUtils; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.state.property.Properties; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; -import org.joml.Matrix4f; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; -public record RecipeBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +public record RecipeBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { private static final Identifier ITEM_TEXTURE = Glowcase.id("textures/item/recipe_block.png"); - public void render(RecipeBlockEntity entity, float f, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (GlowcaseClient.EMI_LOADED) { - matrices.push(); - matrices.translate(0.5D, 0.5D, 0.5D); - - float rotation = -(entity.getCachedState().get(Properties.ROTATION) * 360) / 16.0F; - - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(rotation)); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.rotationY)); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(entity.rotationX)); - - switch (entity.zOffset) { - case FRONT -> matrices.translate(0D, 0D, -0.4D); - case BACK -> matrices.translate(0D, 0D, 0.4D); - case CENTER -> matrices.translate(0D, 0D, 0D); - } - -// boolean rendered = EmiWorldRenderUtils.renderRecipe(matrices, entity.recipe, entity.getPos()); - matrices.pop(); -// if (rendered) return; - } else { - matrices.push(); - matrices.translate(0.5D, 0.5D, 0.5D); - - float rotation = -(entity.getCachedState().get(Properties.ROTATION) * 360) / 16.0F; - - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(rotation)); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.rotationY)); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(entity.rotationX)); - - VertexConsumer buffer = vertexConsumers.getBuffer(RenderLayer.getTextBackground()); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); + public static class RecipeRenderState extends BlockEntityRenderState { + public TextBlockEntity.ZOffset zOffset; + public int rotation16; + } - buffer.vertex(matrix4f, -0.5f, -0.5f, 0f).color(0xFF111111).light(light); - buffer.vertex(matrix4f, -0.5f, 0.5f, 0f).color(0xFF111111).light(light); - buffer.vertex(matrix4f, 0.5f, 0.5f, 0f).color(0xFF111111).light(light); - buffer.vertex(matrix4f, 0.5f, -0.5f, 0f).color(0xFF111111).light(light); + @Override + public RecipeRenderState createRenderState() { + return new RecipeRenderState(); + } - ScreenBlockEntityRenderer.renderTextCentered("EMI not loaded", 0xFFFF8888, 1f, 1f, matrices, vertexConsumers, this.context.getTextRenderer(), light); - matrices.pop(); - } + @Override + public void extractRenderState(RecipeBlockEntity blockEntity, RecipeRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + state.zOffset = blockEntity.zOffset; + state.rotation16 = blockEntity.getBlockState().getValue(BlockStateProperties.ROTATION_16); + } - if (BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos())) { - BlockEntityRenderUtil.renderPlaceholderWithBlockRotation(entity, ITEM_TEXTURE, 1F, matrices, vertexConsumers, entity.zOffset == TextBlockEntity.ZOffset.CENTER ? 0.01F : entity.zOffset == TextBlockEntity.ZOffset.FRONT ? 0.4F : -0.4F); + @Override + public void submit(RecipeRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + if (BlockEntityRenderUtil.shouldRenderPlaceholder(state.blockPos)) { + BlockEntityRenderUtil.renderPlaceholderWithBlockRotation(state, state.rotation16, ITEM_TEXTURE, 1F, poseStack, submitNodeCollector, state.zOffset == TextBlockEntity.ZOffset.CENTER ? 0.01F : state.zOffset == TextBlockEntity.ZOffset.FRONT ? 0.4F : -0.4F); } } +// FIXME 26.1 +// public void render(RecipeBlockEntity entity, float f, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, Vec3 cameraPos) { +// if (GlowcaseClient.EMI_LOADED) { +// matrices.pushPose(); +// matrices.translate(0.5D, 0.5D, 0.5D); +// +// float rotation = -(entity.getBlockState().getValue(BlockStateProperties.ROTATION_16) * 360) / 16.0F; +// +// matrices.mulPose(Axis.YP.rotationDegrees(rotation)); +// matrices.mulPose(Axis.YP.rotationDegrees(180)); +// matrices.mulPose(Axis.YP.rotationDegrees(entity.rotationY)); +// matrices.mulPose(Axis.XP.rotationDegrees(entity.rotationX)); +// +// switch (entity.zOffset) { +// case FRONT -> matrices.translate(0D, 0D, -0.4D); +// case BACK -> matrices.translate(0D, 0D, 0.4D); +// case CENTER -> matrices.translate(0D, 0D, 0D); +// } +// +//// boolean rendered = EmiWorldRenderUtils.renderRecipe(matrices, entity.recipe, entity.getPos()); +// matrices.popPose(); +//// if (rendered) return; +// } else { +// matrices.pushPose(); +// matrices.translate(0.5D, 0.5D, 0.5D); +// +// float rotation = -(entity.getBlockState().getValue(BlockStateProperties.ROTATION_16) * 360) / 16.0F; +// +// matrices.mulPose(Axis.YP.rotationDegrees(rotation)); +// matrices.mulPose(Axis.YP.rotationDegrees(180)); +// matrices.mulPose(Axis.YP.rotationDegrees(entity.rotationY)); +// matrices.mulPose(Axis.XP.rotationDegrees(entity.rotationX)); +// +// VertexConsumer buffer = vertexConsumers.getBuffer(RenderType.textBackground()); +// Matrix4f matrix4f = matrices.last().pose(); +// +// buffer.addVertex(matrix4f, -0.5f, -0.5f, 0f).setColor(0xFF111111).setLight(light); +// buffer.addVertex(matrix4f, -0.5f, 0.5f, 0f).setColor(0xFF111111).setLight(light); +// buffer.addVertex(matrix4f, 0.5f, 0.5f, 0f).setColor(0xFF111111).setLight(light); +// buffer.addVertex(matrix4f, 0.5f, -0.5f, 0f).setColor(0xFF111111).setLight(light); +// +// ScreenBlockEntityRenderer.renderTextCentered("EMI not loaded", 0xFFFF8888, 1f, 1f, matrices, vertexConsumers, this.context.getFont(), light); +// matrices.popPose(); +// } + +// } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ScreenBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ScreenBlockEntityRenderer.java index e98fac20..99307fac 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ScreenBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/ScreenBlockEntityRenderer.java @@ -1,31 +1,39 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.datafixers.util.Pair; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ScreenBlockEntity; import dev.hephaestus.glowcase.client.GlowcaseClient; -import dev.hephaestus.glowcase.client.GlowcaseRenderLayers; +//import dev.hephaestus.glowcase.client.GlowcaseRenderLayers; import dev.hephaestus.glowcase.client.ScreenImageCache; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.render.*; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.state.property.Properties; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.Lightmap; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.rendertype.RenderType; +import net.minecraft.client.renderer.rendertype.RenderTypes; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import java.util.ArrayList; -public record ScreenBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +public record ScreenBlockEntityRenderer(BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/screen_block.png"); public static final int COLOR_SCR_OFF = 0xFF111111; @@ -37,212 +45,226 @@ public record ScreenBlockEntityRenderer(BlockEntityRendererFactory.Context conte public static final int SCR_MAX_LINES = 19; - @Override - public void render(ScreenBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - if (BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos()) || - (MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().player.getMainHandStack().isOf(Glowcase.TABLET_ITEM.get()))) - BlockEntityRenderUtil.renderPlaceholderWithBlockRotation(entity, ITEM_TEXTURE, 1f, matrices, vertexConsumers, -0.1F); - - matrices.push(); - - // Positioning - - matrices.translate(.5f, .5f, .5f); - - float rotation = -(entity.getCachedState().get(Properties.ROTATION) * 360) / 16.0F; - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(rotation)); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); - matrices.translate(entity.getOffset().x(), entity.getOffset().y(), entity.getOffset().z()); - - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.yaw)); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(entity.pitch)); - - // Gather needed variables - - TextRenderer textRenderer = this.context.getTextRenderer(); - - int brightness = entity.eink ? light : LightmapTextureManager.MAX_LIGHT_COORDINATE; - - String url = entity.url; - - boolean renderBackface = entity.renderBackface; - - // Screen width.height - float width = entity.width; - float height = entity.height; - - float x1 = -width / 2f; - float x2 = width / 2f; - float y1 = -height / 2f; - float y2 = height / 2f; - - // Start drawing screen - - if (url.isEmpty()) { - // Blank screen - renderFilledRectangle(COLOR_SCR_OFF, x1, x2, y1, y2, vertexConsumers, matrices, brightness); - renderTextCentered(Text.stringifiedTranslatable("gui.glowcase.screen.blank"), COLOR_TXT_NORMAL, width, height, matrices, vertexConsumers, textRenderer, brightness); - } else { - ScreenImageCache screenImageCache = GlowcaseClient.screenImageCache; - ScreenImageCache.ScreenTexture image = screenImageCache.getImage(url, entity.getPos()); - Pair response = image.getTexture(); - - int code = response.getFirst(); - @Nullable Identifier texture = response.getSecond(); - - if (texture != null) { - if (!entity.stretch) { - Pair scale = getScale(width, height, image.getWidth(), image.getHeight()); - - Float scaled_width = scale.getFirst(); - Float scaled_height = scale.getSecond(); - - x1 = -scaled_width / 2f; - x2 = scaled_width / 2f; - y1 = -scaled_height / 2f; - y2 = scaled_height / 2f; - } - - // Actual picture - renderPicture(texture, x1, x2, y1, y2, vertexConsumers, matrices, brightness, renderBackface); - } else if (code / 100 == 1) { - // Loading screen - renderFilledRectangle(COLOR_SCR_ON, x1, x2, y1, y2, vertexConsumers, matrices, brightness); - - int frame = (int) (((System.currentTimeMillis() % 4000L) / 250L) % 4); - String animation = switch (frame) { - case 0 -> "Ooo"; - case 2 -> "ooO"; - default -> "oOo"; - }; - renderTextCentered(animation, COLOR_TXT_NORMAL, width, height, matrices, vertexConsumers, textRenderer, brightness); - } else { - // Bluescreen - renderFilledRectangle(COLOR_SCR_BLUE, x1, x2, y1, y2, vertexConsumers, matrices, brightness); - renderErrCode(code, entity, width, height, vertexConsumers, matrices, textRenderer, brightness); - } - } - - matrices.pop(); - } - - public static void renderPicture(@NotNull Identifier texture, float x1, float x2, float y1, float y2, VertexConsumerProvider vertexConsumers, MatrixStack matrices, int light, boolean renderBackface) { - RenderLayer renderLayer = GlowcaseRenderLayers.getScreen(texture, !renderBackface); - VertexConsumer buffer = vertexConsumers.getBuffer(renderLayer); - - MatrixStack.Entry matrix = matrices.peek(); - Matrix4f matrix4f = matrix.getPositionMatrix(); - - buffer.vertex(matrix4f, x1, y1, 0f).color(0xFFFFFFFF).texture(1f, 1f).overlay(OverlayTexture.DEFAULT_UV).light(light).normal(matrix, 0f, 0f, 1f); - buffer.vertex(matrix4f, x1, y2, 0f).color(0xFFFFFFFF).texture(1f, 0f).overlay(OverlayTexture.DEFAULT_UV).light(light).normal(matrix, 0f, 0f, 1f); - buffer.vertex(matrix4f, x2, y2, 0f).color(0xFFFFFFFF).texture(0f, 0f).overlay(OverlayTexture.DEFAULT_UV).light(light).normal(matrix, 0f, 0f, 1f); - buffer.vertex(matrix4f, x2, y1, 0f).color(0xFFFFFFFF).texture(0f, 1f).overlay(OverlayTexture.DEFAULT_UV).light(light).normal(matrix, 0f, 0f, 1f); - } - - /** - *

Responsible for the blue screen of death. - * This screen is always being rendered whenever it could not fetch a given image.

- * - *

As a replacement for the wanted image, an alternative text description - * as well as the reason why it did not show the text is being shown here.

- * - *

Note: The code within this method is very messy and someone might want to improve this in the future.

- * - * @param code Error code - * @param width Width of the screen - * @param height Height of the screen - */ - public static void renderErrCode(int code, ScreenBlockEntity entity, float width, float height, VertexConsumerProvider vertexConsumers, MatrixStack matrices, TextRenderer textRenderer, int light) { - // Setup font - float lineHeight = height / SCR_MAX_LINES; - float font_scale = lineHeight / textRenderer.fontHeight; - - float txt_width = width * 0.95f; - float txt_gap = width * 0.05f; + public static class ScreenRenderState extends BlockEntityRenderState { - matrices.translate(txt_width / 2f - (txt_gap / 2f), height / 2f - (lineHeight / 2f), -.1f); // Upper-Left corner - matrices.scale(-font_scale, -font_scale, -.1f); - - // Alt-Text - - String alt = Text.translatable("gui.glowcase.screen.alt", entity.alt).getString(); - ArrayList lines = wrap(alt, font_scale, txt_width, textRenderer); - - matrices.translate(0, textRenderer.fontHeight * ((int) (SCR_MAX_LINES / 2) - 1), 0f); // Move to second half of screen - - int moved_lines = 0; - for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i); - - // No overflows here - int limit = (SCR_MAX_LINES / 2 - 1); - if (i > limit) - break; - else if (i == limit && i + 1 != lines.size()) - line = line + "…"; - - moved_lines++; - matrices.translate(0, textRenderer.fontHeight, 0f); // One line down - textRenderer.draw(line, 0, 0, COLOR_TXT_CRASH, true, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, light); - } - - // Error message - - matrices.translate(0, -textRenderer.fontHeight * ((int) (SCR_MAX_LINES / 2) - 1), 0f); // Move cursor back to Upper-Left - matrices.translate(0, -textRenderer.fontHeight * moved_lines, 0f); - - matrices.translate(0, textRenderer.fontHeight * 4, 0f); - - MutableText hint = Text.translatableWithFallback("gui.glowcase.screen.hint." + code, ""); - String error_msg = Text.translatable("gui.glowcase.screen.error", code).append(" ").append(hint).getString(); - lines = wrap(error_msg, font_scale, txt_width, textRenderer); - - moved_lines = 0; - for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i); - - // No overflows here - int limit = (SCR_MAX_LINES / 2) - 7; - if (i > limit) - break; - else if (i == limit && i + 1 != lines.size()) - line = line + "…"; - - moved_lines++; - matrices.translate(0, textRenderer.fontHeight, 0f); // One line down - textRenderer.draw(line, 0, 0, COLOR_TXT_CRASH, true, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, light); - } - - // Important face - - matrices.translate(0, -textRenderer.fontHeight * (moved_lines + 3), 0f); // Undo cursor positioning - matrices.scale(3f, 3f, 1f); - textRenderer.draw(":3", 0, 0, COLOR_TXT_CRASH, true, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, light); } - @SuppressWarnings("SameParameterValue") - public static void renderTextCentered(String text, int color, float scr_width, float scr_height, MatrixStack matrices, VertexConsumerProvider vertexConsumers, TextRenderer textRenderer, int light) { - renderTextCentered(Text.literal(text), color, scr_width, scr_height, matrices, vertexConsumers, textRenderer, light); + @Override + public ScreenRenderState createRenderState() { + return new ScreenRenderState(); } - public static void renderTextCentered(MutableText text, int color, float scr_width, float scr_height, MatrixStack matrices, VertexConsumerProvider vertexConsumers, TextRenderer textRenderer, int light) { - // Scale font - float max_font_width = scr_width / textRenderer.getWidth(text); - float max_font_height = scr_height / textRenderer.fontHeight; - - float font_scale_factor = Math.min(max_font_width, max_font_height) * .6f; - - // Apply - matrices.scale(-font_scale_factor, -font_scale_factor, -0.5f); - matrices.translate(-textRenderer.getWidth(text) / 2f, -textRenderer.fontHeight / 2f, .1f); // Remove offset of string + @Override + public void submit(ScreenRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { - textRenderer.draw(text, 0, 0, color, true, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, light); } - - /** - * Returns the scale factors needed to ensure a picture does not go out of bounds of the given width/height. - */ +// FIXME 26.1 +// @Override +// public void render(ScreenBlockEntity entity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, Vec3 cameraPos) { +// if (entity.getLevel() == null || entity.getLevel().getBlockState(entity.getBlockPos()).isAir()) return; +// if (BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getBlockPos()) || +// (Minecraft.getInstance().player != null && Minecraft.getInstance().player.getMainHandItem().is(Glowcase.TABLET_ITEM.get()))) +// BlockEntityRenderUtil.renderPlaceholderWithBlockRotation(entity, ITEM_TEXTURE, 1f, matrices, vertexConsumers, -0.1F); +// +// matrices.pushPose(); +// +// // Positioning +// +// matrices.translate(.5f, .5f, .5f); +// +// float rotation = -(entity.getBlockState().getValue(BlockStateProperties.ROTATION_16) * 360) / 16.0F; +// matrices.mulPose(Axis.YP.rotationDegrees(rotation)); +// matrices.mulPose(Axis.YP.rotationDegrees(180)); +// matrices.translate(entity.getOffset().x(), entity.getOffset().y(), entity.getOffset().z()); +// +// matrices.mulPose(Axis.YP.rotationDegrees(entity.yaw)); +// matrices.mulPose(Axis.XP.rotationDegrees(entity.pitch)); +// +// // Gather needed variables +// +// Font textRenderer = this.context.getFont(); +// +// int brightness = entity.eink ? light : Lightmap.FULL_BRIGHT; +// +// String url = entity.url; +// +// boolean renderBackface = entity.renderBackface; +// +// // Screen width.height +// float width = entity.width; +// float height = entity.height; +// +// float x1 = -width / 2f; +// float x2 = width / 2f; +// float y1 = -height / 2f; +// float y2 = height / 2f; +// +// // Start drawing screen +// +// if (url.isEmpty()) { +// // Blank screen +// renderFilledRectangle(COLOR_SCR_OFF, x1, x2, y1, y2, vertexConsumers, matrices, brightness); +// renderTextCentered(Component.translatableEscape("gui.glowcase.screen.blank"), COLOR_TXT_NORMAL, width, height, matrices, vertexConsumers, textRenderer, brightness); +// } else { +// ScreenImageCache screenImageCache = GlowcaseClient.screenImageCache; +// ScreenImageCache.ScreenTexture image = screenImageCache.getImage(url, entity.getBlockPos()); +// Pair response = image.getTexture(); +// +// int code = response.getFirst(); +// @Nullable Identifier texture = response.getSecond(); +// +// if (texture != null) { +// if (!entity.stretch) { +// Pair scale = getScale(width, height, image.getWidth(), image.getHeight()); +// +// Float scaled_width = scale.getFirst(); +// Float scaled_height = scale.getSecond(); +// +// x1 = -scaled_width / 2f; +// x2 = scaled_width / 2f; +// y1 = -scaled_height / 2f; +// y2 = scaled_height / 2f; +// } +// +// // Actual picture +// renderPicture(texture, x1, x2, y1, y2, vertexConsumers, matrices, brightness, renderBackface); +// } else if (code / 100 == 1) { +// // Loading screen +// renderFilledRectangle(COLOR_SCR_ON, x1, x2, y1, y2, vertexConsumers, matrices, brightness); +// +// int frame = (int) (((System.currentTimeMillis() % 4000L) / 250L) % 4); +// String animation = switch (frame) { +// case 0 -> "Ooo"; +// case 2 -> "ooO"; +// default -> "oOo"; +// }; +// renderTextCentered(animation, COLOR_TXT_NORMAL, width, height, matrices, vertexConsumers, textRenderer, brightness); +// } else { +// // Bluescreen +// renderFilledRectangle(COLOR_SCR_BLUE, x1, x2, y1, y2, vertexConsumers, matrices, brightness); +// renderErrCode(code, entity, width, height, vertexConsumers, matrices, textRenderer, brightness); +// } +// } +// +// matrices.popPose(); +// } +// +// public static void renderPicture(@NotNull Identifier texture, float x1, float x2, float y1, float y2, MultiBufferSource vertexConsumers, PoseStack matrices, int light, boolean renderBackface) { +// RenderType renderLayer = GlowcaseRenderLayers.getScreen(texture, !renderBackface); +// VertexConsumer buffer = vertexConsumers.getBuffer(renderLayer); +// +// PoseStack.Pose matrix = matrices.last(); +// Matrix4f matrix4f = matrix.pose(); +// +// buffer.addVertex(matrix4f, x1, y1, 0f).setColor(0xFFFFFFFF).setUv(1f, 1f).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(matrix, 0f, 0f, 1f); +// buffer.addVertex(matrix4f, x1, y2, 0f).setColor(0xFFFFFFFF).setUv(1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(matrix, 0f, 0f, 1f); +// buffer.addVertex(matrix4f, x2, y2, 0f).setColor(0xFFFFFFFF).setUv(0f, 0f).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(matrix, 0f, 0f, 1f); +// buffer.addVertex(matrix4f, x2, y1, 0f).setColor(0xFFFFFFFF).setUv(0f, 1f).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(matrix, 0f, 0f, 1f); +// } +// +// /** +// *

Responsible for the blue screen of death. +// * This screen is always being rendered whenever it could not fetch a given image.

+// * +// *

As a replacement for the wanted image, an alternative text description +// * as well as the reason why it did not show the text is being shown here.

+// * +// *

Note: The code within this method is very messy and someone might want to improve this in the future.

+// * +// * @param code Error code +// * @param width Width of the screen +// * @param height Height of the screen +// */ +// public static void renderErrCode(int code, ScreenBlockEntity entity, float width, float height, MultiBufferSource vertexConsumers, PoseStack matrices, Font textRenderer, int light) { +// // Setup font +// float lineHeight = height / SCR_MAX_LINES; +// float font_scale = lineHeight / textRenderer.lineHeight; +// +// float txt_width = width * 0.95f; +// float txt_gap = width * 0.05f; +// +// matrices.translate(txt_width / 2f - (txt_gap / 2f), height / 2f - (lineHeight / 2f), -.1f); // Upper-Left corner +// matrices.scale(-font_scale, -font_scale, -.1f); +// +// // Alt-Text +// +// String alt = Component.translatable("gui.glowcase.screen.alt", entity.alt).getString(); +// ArrayList lines = wrap(alt, font_scale, txt_width, textRenderer); +// +// matrices.translate(0, textRenderer.lineHeight * ((int) (SCR_MAX_LINES / 2) - 1), 0f); // Move to second half of screen +// +// int moved_lines = 0; +// for (int i = 0; i < lines.size(); i++) { +// String line = lines.get(i); +// +// // No overflows here +// int limit = (SCR_MAX_LINES / 2 - 1); +// if (i > limit) +// break; +// else if (i == limit && i + 1 != lines.size()) +// line = line + "…"; +// +// moved_lines++; +// matrices.translate(0, textRenderer.lineHeight, 0f); // One line down +// textRenderer.drawInBatch(line, 0, 0, COLOR_TXT_CRASH, true, matrices.last().pose(), vertexConsumers, Font.DisplayMode.NORMAL, 0, light); +// } +// +// // Error message +// +// matrices.translate(0, -textRenderer.lineHeight * ((int) (SCR_MAX_LINES / 2) - 1), 0f); // Move cursor back to Upper-Left +// matrices.translate(0, -textRenderer.lineHeight * moved_lines, 0f); +// +// matrices.translate(0, textRenderer.lineHeight * 4, 0f); +// +// MutableComponent hint = Component.translatableWithFallback("gui.glowcase.screen.hint." + code, ""); +// String error_msg = Component.translatable("gui.glowcase.screen.error", code).append(" ").append(hint).getString(); +// lines = wrap(error_msg, font_scale, txt_width, textRenderer); +// +// moved_lines = 0; +// for (int i = 0; i < lines.size(); i++) { +// String line = lines.get(i); +// +// // No overflows here +// int limit = (SCR_MAX_LINES / 2) - 7; +// if (i > limit) +// break; +// else if (i == limit && i + 1 != lines.size()) +// line = line + "…"; +// +// moved_lines++; +// matrices.translate(0, textRenderer.lineHeight, 0f); // One line down +// textRenderer.drawInBatch(line, 0, 0, COLOR_TXT_CRASH, true, matrices.last().pose(), vertexConsumers, Font.DisplayMode.NORMAL, 0, light); +// } +// +// // Important face +// +// matrices.translate(0, -textRenderer.lineHeight * (moved_lines + 3), 0f); // Undo cursor positioning +// matrices.scale(3f, 3f, 1f); +// textRenderer.drawInBatch(":3", 0, 0, COLOR_TXT_CRASH, true, matrices.last().pose(), vertexConsumers, Font.DisplayMode.NORMAL, 0, light); +// } +// +// @SuppressWarnings("SameParameterValue") +// public static void renderTextCentered(String text, int color, float scr_width, float scr_height, PoseStack matrices, MultiBufferSource vertexConsumers, Font textRenderer, int light) { +// renderTextCentered(Component.literal(text), color, scr_width, scr_height, matrices, vertexConsumers, textRenderer, light); +// } +// +// public static void renderTextCentered(MutableComponent text, int color, float scr_width, float scr_height, PoseStack matrices, MultiBufferSource vertexConsumers, Font textRenderer, int light) { +// // Scale font +// float max_font_width = scr_width / textRenderer.width(text); +// float max_font_height = scr_height / textRenderer.lineHeight; +// +// float font_scale_factor = Math.min(max_font_width, max_font_height) * .6f; +// +// // Apply +// matrices.scale(-font_scale_factor, -font_scale_factor, -0.5f); +// matrices.translate(-textRenderer.width(text) / 2f, -textRenderer.lineHeight / 2f, .1f); // Remove offset of string +// +// textRenderer.drawInBatch(text, 0, 0, color, true, matrices.last().pose(), vertexConsumers, Font.DisplayMode.NORMAL, 0, light); +// } +// +// /** +// * Returns the scale factors needed to ensure a picture does not go out of bounds of the given width/height. +// */ public static Pair getScale(float width, float height, int img_width, int img_height) { float width_scale = width / img_width; float height_scale = height / img_height; @@ -253,51 +275,51 @@ public static Pair getScale(float width, float height, int img_wid return new Pair<>(scaled_width, scaled_height); } - - /** - * Used to trim off the string to fit the given width in a way where words are not broken apart. - * (aka Word wrapping) - * - * @param font_scale Size of the font in relation to the screens sizes. - * @param txt_width Available width of the screen for the text. - * @return A list of strings where all fit in the expected width. - */ - private static ArrayList wrap(String text, float font_scale, float txt_width, TextRenderer textRenderer) { - ArrayList result = new ArrayList<>(); - - StringBuilder lineBuilder = new StringBuilder(); - - for (String word : text.split(" ")) { - if ((textRenderer.getWidth(lineBuilder + word) * font_scale) >= txt_width) { - result.add(lineBuilder.toString().trim()); - lineBuilder = new StringBuilder(); - } - lineBuilder.append(word).append(" "); - } - - if (!lineBuilder.isEmpty()) - result.add(lineBuilder.toString().trim()); - - return result; - } - - private static void renderFilledRectangle(int color, float x1, float x2, float y1, float y2, VertexConsumerProvider vertexConsumers, MatrixStack matrices, int light) { - VertexConsumer buffer = vertexConsumers.getBuffer(RenderLayer.getTextBackground()); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - - buffer.vertex(matrix4f, x1, y1, 0f).color(color).light(light); - buffer.vertex(matrix4f, x1, y2, 0f).color(color).light(light); - buffer.vertex(matrix4f, x2, y2, 0f).color(color).light(light); - buffer.vertex(matrix4f, x2, y1, 0f).color(color).light(light); - } +// +// /** +// * Used to trim off the string to fit the given width in a way where words are not broken apart. +// * (aka Word wrapping) +// * +// * @param font_scale Size of the font in relation to the screens sizes. +// * @param txt_width Available width of the screen for the text. +// * @return A list of strings where all fit in the expected width. +// */ +// private static ArrayList wrap(String text, float font_scale, float txt_width, Font textRenderer) { +// ArrayList result = new ArrayList<>(); +// +// StringBuilder lineBuilder = new StringBuilder(); +// +// for (String word : text.split(" ")) { +// if ((textRenderer.width(lineBuilder + word) * font_scale) >= txt_width) { +// result.add(lineBuilder.toString().trim()); +// lineBuilder = new StringBuilder(); +// } +// lineBuilder.append(word).append(" "); +// } +// +// if (!lineBuilder.isEmpty()) +// result.add(lineBuilder.toString().trim()); +// +// return result; +// } +// +// private static void renderFilledRectangle(int color, float x1, float x2, float y1, float y2, MultiBufferSource vertexConsumers, PoseStack matrices, int light) { +// VertexConsumer buffer = vertexConsumers.getBuffer(RenderTypes.textBackground()); +// Matrix4f matrix4f = matrices.last().pose(); +// +// buffer.addVertex(matrix4f, x1, y1, 0f).setColor(color).setLight(light); +// buffer.addVertex(matrix4f, x1, y2, 0f).setColor(color).setLight(light); +// buffer.addVertex(matrix4f, x2, y2, 0f).setColor(color).setLight(light); +// buffer.addVertex(matrix4f, x2, y1, 0f).setColor(color).setLight(light); +// } @Override - public boolean rendersOutsideBoundingBox() { + public boolean shouldRenderOffScreen() { return true; } @Override - public boolean isInRenderDistance(ScreenBlockEntity blockEntity, Vec3d pos) { + public boolean shouldRender(ScreenBlockEntity blockEntity, Vec3 vec3) { return true; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SoundPlayerBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SoundPlayerBlockEntityRenderer.java index 9b41e861..732b1d87 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SoundPlayerBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SoundPlayerBlockEntityRenderer.java @@ -1,23 +1,32 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.SoundPlayerBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.Vec3d; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.resources.Identifier; -public record SoundPlayerBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +public record SoundPlayerBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/sound_block.png"); + public static class SoundPlayerRenderState extends BlockEntityRenderState { + } + + @Override + public SoundPlayerRenderState createRenderState() { + return new SoundPlayerRenderState(); + } + @Override - public void render(SoundPlayerBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - if (BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos(), false)) { - BlockEntityRenderUtil.renderBillboardPlaceholder(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers, context.getRenderDispatcher().camera); + public void submit(SoundPlayerRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + if (BlockEntityRenderUtil.shouldRenderPlaceholder(state.blockPos, false)) { + BlockEntityRenderUtil.renderBillboardPlaceholder(state, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector, camera); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SpriteBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SpriteBlockEntityRenderer.java index b9cb755c..0bee6aa9 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SpriteBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/SpriteBlockEntityRenderer.java @@ -1,129 +1,143 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; import dev.hephaestus.glowcase.Glowcase; +import dev.hephaestus.glowcase.block.SpriteBlock; import dev.hephaestus.glowcase.block.entity.SpriteBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import dev.hephaestus.glowcase.client.util.ModMetaUtil; -import dev.hephaestus.glowcase.mixin.client.TextureManagerAccessor; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRenderer; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.resource.ResourceManager; -import net.minecraft.state.property.Properties; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.core.Direction; +import net.minecraft.resources.Identifier; +import net.minecraft.world.phys.Vec3; import org.joml.Vector3f; +import org.jspecify.annotations.Nullable; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -public record SpriteBlockEntityRenderer(BlockEntityRendererFactory.Context context) implements BlockEntityRenderer { +public record SpriteBlockEntityRenderer( + BlockEntityRendererProvider.Context context) implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/sprite_block.png"); private static final Map modIconCache = new ConcurrentHashMap<>(); - private static final Vector3f[] vertices = new Vector3f[] { + private static final Vector3f[] vertices = new Vector3f[]{ new Vector3f(-0.5F, -0.5F, 0.0F), new Vector3f(0.5F, -0.5F, 0.0F), new Vector3f(0.5F, 0.5F, 0.0F), new Vector3f(-0.5F, 0.5F, 0.0F) }; - public void render(SpriteBlockEntity entity, float f, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - matrices.push(); - matrices.translate(0.5D, 0.5D, 0.5D); - - matrices.multiply(entity.getCachedState().get(Properties.FACING).getRotationQuaternion().mul(RotationAxis.POSITIVE_X.rotationDegrees(-90.0F))); - matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(entity.rotation)); - - switch (entity.zOffset) { - case FRONT -> matrices.translate(0D, 0D, 0.4D); - case BACK -> matrices.translate(0D, 0D, -0.4D); - } + public static class SpriteRenderState extends BlockEntityRenderState { + public String sprite; + public Direction facing; + } - matrices.scale(entity.scale, entity.scale, entity.scale); + @Override + public SpriteRenderState createRenderState() { + return new SpriteRenderState(); + } - MinecraftClient client = MinecraftClient.getInstance(); - var entry = matrices.peek(); - if (entity.getRenderItem() != null) { - client.getItemRenderer().renderItem(entity.getRenderItem(), - ItemDisplayContext.FIXED, light, overlay, matrices, vertexConsumers, entity.getWorld(), 0); - } else { - Identifier identifier = Identifier.tryParse(Glowcase.MODID, "textures/sprite/" + entity.getSprite() + ".png"); - boolean isMod = false; // Used for the invalid texture check further down - if (identifier == null) { - // Identifiers ending in / are always invalid, but tryParse logs an error when attempting to parse. - // Just force the identifier to null here instead. - identifier = entity.getSprite().endsWith("/") ? null : Identifier.tryParse(entity.getSprite()); - if (identifier == null) { - identifier = Glowcase.id("textures/sprite/invalid.png"); - } else if (identifier.getNamespace().equals("mod")) { // Special mod namespace uses mod icon. - String modId = identifier.getPath(); - if (!modIconCache.containsKey(modId)) { - // Attempt to register mod icon and put it into the cache. Invalid icons will fall to - // the else branch and use the invalid icon. - Optional mod = FabricLoader.getInstance().getModContainer(modId) - .or(() -> FabricLoader.getInstance().getModContainer(modId.replace("_", "-"))) - .or(() -> FabricLoader.getInstance().getModContainer(modId.replace("_", ""))); - NativeImageBackedTexture icon = mod.map(modContainer -> ModMetaUtil.getIcon(modContainer, 64 * client.options.getGuiScale().getValue())).orElse(null); - if (icon != null) { - // Needs to end in .png for the missing texture check further below. - modIconCache.put(modId, Identifier.of(Glowcase.MODID, modId + "_icon.png")); - client.getTextureManager().registerTexture(modIconCache.get(modId), icon); - identifier = modIconCache.get(modId); - } else { - identifier = Glowcase.id("textures/sprite/invalid.png"); - } - } else { - // Mod is in the cache, just grab the identifier for it. - identifier = modIconCache.get(modId); - isMod = true; - } - } - } - TextureManager textureManager = client.getTextureManager(); - ResourceManager resourceManager = ((TextureManagerAccessor) textureManager).glowcase$getResourceManager(); - if (resourceManager.getResource(identifier).isEmpty() && !isMod || !identifier.getPath().endsWith(".png")) { - /* - If the texture (file) does not exist, just replace it. - This happens a lot when editing a sprite block, so I'm adding it to avoid log spam - - SkyNotTheLimit - */ - identifier = Glowcase.id("textures/sprite/invalid.png"); - } - var vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getEntityCutout(identifier)); + @Override + public void extractRenderState(SpriteBlockEntity blockEntity, SpriteRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + state.sprite = blockEntity.getSprite(); + state.facing = blockEntity.getBlockState().getValue(SpriteBlock.FACING); + } - vertex(entry, vertexConsumer, vertices[0], 0, 1, entity.color); - vertex(entry, vertexConsumer, vertices[1], 1, 1, entity.color); - vertex(entry, vertexConsumer, vertices[2], 1, 0, entity.color); - vertex(entry, vertexConsumer, vertices[3], 0, 0, entity.color); + @Override + public void submit(SpriteRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + if (state.sprite.isEmpty() || BlockEntityRenderUtil.shouldRenderPlaceholder(state.blockPos)) { + BlockEntityRenderUtil.renderFacingPlaceholder(state, state.facing, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector); } - - matrices.pop(); - - if (entity.getSprite().isEmpty() || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos())) BlockEntityRenderUtil.renderFacingPlaceholder(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers); } - private void vertex( - MatrixStack.Entry matrix, VertexConsumer vertexConsumer, Vector3f vertex, float u, float v, int color) { - vertexConsumer.vertex(matrix, vertex.x(), vertex.y(), vertex.z()) - .color(color) - .texture(u, v) - .overlay(OverlayTexture.DEFAULT_UV) - .light(LightmapTextureManager.MAX_LIGHT_COORDINATE) - .normal(0, 1, 0); - } + // FIXME 26.1 +// public void render(SpriteBlockEntity entity, float f, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, Vec3 cameraPos) { +// if (entity.getLevel() == null || entity.getLevel().getBlockState(entity.getBlockPos()).isAir()) return; +// matrices.pushPose(); +// matrices.translate(0.5D, 0.5D, 0.5D); +// +// matrices.mulPose(entity.getBlockState().getValue(BlockStateProperties.FACING).getRotation().mul(Axis.XP.rotationDegrees(-90.0F))); +// matrices.mulPose(Axis.ZN.rotationDegrees(entity.rotation)); +// +// switch (entity.zOffset) { +// case FRONT -> matrices.translate(0D, 0D, 0.4D); +// case BACK -> matrices.translate(0D, 0D, -0.4D); +// } +// +// matrices.scale(entity.scale, entity.scale, entity.scale); +// +// Minecraft client = Minecraft.getInstance(); +// var entry = matrices.last(); +// if (entity.getRenderItem() != null) { +// client.getItemRenderer().renderStatic(entity.getRenderItem(), +// ItemDisplayContext.FIXED, light, overlay, matrices, vertexConsumers, entity.getLevel(), 0); +// } else { +// Identifier identifier = Identifier.tryBuild(Glowcase.MODID, "textures/sprite/" + entity.getSprite() + ".png"); +// boolean isMod = false; // Used for the invalid texture check further down +// if (identifier == null) { +// // Identifiers ending in / are always invalid, but tryParse logs an error when attempting to parse. +// // Just force the identifier to null here instead. +// identifier = entity.getSprite().endsWith("/") ? null : Identifier.tryParse(entity.getSprite()); +// if (identifier == null) { +// identifier = Glowcase.id("textures/sprite/invalid.png"); +// } else if (identifier.getNamespace().equals("mod")) { // Special mod namespace uses mod icon. +// String modId = identifier.getPath(); +// if (!modIconCache.containsKey(modId)) { +// // Attempt to register mod icon and put it into the cache. Invalid icons will fall to +// // the else branch and use the invalid icon. +// Optional mod = FabricLoader.getInstance().getModContainer(modId) +// .or(() -> FabricLoader.getInstance().getModContainer(modId.replace("_", "-"))) +// .or(() -> FabricLoader.getInstance().getModContainer(modId.replace("_", ""))); +// DynamicTexture icon = mod.map(modContainer -> ModMetaUtil.getIcon(modContainer, 64 * client.options.guiScale().get())).orElse(null); +// if (icon != null) { +// // Needs to end in .png for the missing texture check further below. +// modIconCache.put(modId, Identifier.fromNamespaceAndPath(Glowcase.MODID, modId + "_icon.png")); +// client.getTextureManager().register(modIconCache.get(modId), icon); +// identifier = modIconCache.get(modId); +// } else { +// identifier = Glowcase.id("textures/sprite/invalid.png"); +// } +// } else { +// // Mod is in the cache, just grab the identifier for it. +// identifier = modIconCache.get(modId); +// isMod = true; +// } +// } +// } +// TextureManager textureManager = client.getTextureManager(); +// ResourceManager resourceManager = ((TextureManagerAccessor) textureManager).glowcase$getResourceManager(); +// if (resourceManager.getResource(identifier).isEmpty() && !isMod || !identifier.getPath().endsWith(".png")) { +// /* +// If the texture (file) does not exist, just replace it. +// This happens a lot when editing a sprite block, so I'm adding it to avoid log spam +// - SkyNotTheLimit +// */ +// identifier = Glowcase.id("textures/sprite/invalid.png"); +// } +// var vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(identifier)); +// +// vertex(entry, vertexConsumer, vertices[0], 0, 1, entity.color); +// vertex(entry, vertexConsumer, vertices[1], 1, 1, entity.color); +// vertex(entry, vertexConsumer, vertices[2], 1, 0, entity.color); +// vertex(entry, vertexConsumer, vertices[3], 0, 0, entity.color); +// } +// +// matrices.popPose(); +//// } +// +// private void vertex( +// PoseStack.Pose matrix, VertexConsumer vertexConsumer, Vector3f vertex, float u, float v, int color) { +// vertexConsumer.addVertex(matrix, vertex.x(), vertex.y(), vertex.z()) +// .setColor(color) +// .setUv(u, v) +// .setOverlay(OverlayTexture.NO_OVERLAY) +// .setLight(Lightmap.FULL_BRIGHT) +// .setNormal(0, 1, 0); +// } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java index 21c12c47..da21ed4d 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java @@ -1,162 +1,178 @@ package dev.hephaestus.glowcase.client.render.block.entity; +import com.mojang.blaze3d.vertex.PoseStack; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; import dev.hephaestus.glowcase.client.util.BlockEntityRenderUtil; -import dev.hephaestus.glowcase.mixin.client.TextRendererAccessor; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.BakedGlyph; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.state.property.Properties; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -public class TextBlockEntityRenderer extends BakedBlockEntityRenderer { +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; + +public class TextBlockEntityRenderer implements BlockEntityRenderer { public static Identifier ITEM_TEXTURE = Glowcase.id("textures/item/text_block.png"); private boolean wasOutOfRange = false; - public TextBlockEntityRenderer(BlockEntityRendererFactory.Context context) { - super(context); + public static class TextRenderState extends BlockEntityRenderState { + public boolean shouldRenderPlaceholder; + public TextBlockEntity.ZOffset zOffset; + public int rotation16; } @Override - public boolean shouldBake(TextBlockEntity entity) { - return !entity.lines.isEmpty(); + public TextRenderState createRenderState() { + return new TextRenderState(); } @Override - public void renderUnbaked(TextBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos) { - Entity camera = MinecraftClient.getInstance().getCameraEntity(); - if (camera != null && entity.viewDistance >= 0) { - double dx = camera.getX() - (entity.getPos().getX() + 0.5); - double dy = camera.getY() - (entity.getPos().getY() + 0.5); - double dz = camera.getZ() - (entity.getPos().getZ() + 0.5); - - if ((dx * dx + dy * dy + dz * dz) > (entity.viewDistance * entity.viewDistance)) { - if (!wasOutOfRange) { - entity.renderDirty = true; - wasOutOfRange = true; - } - } else { - if (wasOutOfRange) { - entity.renderDirty = true; - } - - wasOutOfRange = false; - } - } - - if (entity.renderDirty) { - entity.renderDirty = false; - BakedBlockEntityRenderer.Manager.markForRebuild(entity.getPos()); - } - - if (entity.getWorld() == null || entity.getWorld().getBlockState(entity.getPos()).isAir()) return; - if (entity.lines.stream().allMatch(t -> t.getString().isBlank()) || BlockEntityRenderUtil.shouldRenderPlaceholder(entity.getPos())) BlockEntityRenderUtil.renderPlaceholderWithBlockRotation(entity, ITEM_TEXTURE, 1.0F, matrices, vertexConsumers, entity.zOffset == TextBlockEntity.ZOffset.CENTER ? 0.01F : entity.zOffset == TextBlockEntity.ZOffset.FRONT ? 0.4F : -0.4F); + public void extractRenderState(TextBlockEntity blockEntity, TextRenderState state, float partialTicks, Vec3 cameraPosition, ModelFeatureRenderer.@Nullable CrumblingOverlay breakProgress) { + BlockEntityRenderer.super.extractRenderState(blockEntity, state, partialTicks, cameraPosition, breakProgress); + state.shouldRenderPlaceholder = blockEntity.lines.stream().allMatch(t -> t.getString().isBlank()) || BlockEntityRenderUtil.shouldRenderPlaceholder(blockEntity.getBlockPos()); + state.zOffset = blockEntity.zOffset; + state.rotation16 = blockEntity.getBlockState().getValue(BlockStateProperties.ROTATION_16); } @Override - public void renderBaked(TextBlockEntity entity, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) { - Entity camera = MinecraftClient.getInstance().getCameraEntity(); - if (camera != null && entity.viewDistance >= 0) { - double dx = camera.getX() - (entity.getPos().getX() + 0.5); - double dy = camera.getY() - (entity.getPos().getY() + 0.5); - double dz = camera.getZ() - (entity.getPos().getZ() + 0.5); - - if ((dx * dx + dy * dy + dz * dz) > (entity.viewDistance * entity.viewDistance)) { - if (!wasOutOfRange) { - entity.renderDirty = true; - wasOutOfRange = true; - } - - return; - } else { - if (wasOutOfRange) { - entity.renderDirty = true; - } - - wasOutOfRange = false; - } - } - - matrices.push(); - matrices.translate(0.5D, 0.5D, 0.5D); - - float rotation = -(entity.getCachedState().get(Properties.ROTATION) * 360) / 16.0F; - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(rotation)); - - switch (entity.zOffset) { - case FRONT -> matrices.translate(0D, 0D, 0.4D); - case BACK -> matrices.translate(0D, 0D, -0.4D); - } - - float scale = 0.010416667F * entity.scale; - matrices.scale(scale, -scale, scale); - TextRenderer textRenderer = this.context.getTextRenderer(); - - double maxLength = 0; - double minLength = Double.MAX_VALUE; - for (int i = 0; i < entity.lines.size(); ++i) { - maxLength = Math.max(maxLength, textRenderer.getWidth(entity.lines.get(i))); - minLength = Math.min(minLength, textRenderer.getWidth(entity.lines.get(i))); - } - - matrices.translate(0, -((entity.lines.size() - 0.25) * 12) / 2D, 0D); - for (int i = 0; i < entity.lines.size(); ++i) { - Text line = entity.lines.get(i); - double width = textRenderer.getWidth(line); - if (width == 0) continue; - - double dX = switch (entity.textAlignment) { - case LEFT -> -maxLength / 2D; - case CENTER -> (maxLength - width) / 2D - maxLength / 2D; - case CENTER_LEFT -> -(50D / entity.scale) - (width / 2D); - case CENTER_RIGHT -> (50D / entity.scale) - (width / 2D); - case RIGHT -> maxLength - width - maxLength / 2D; - }; - - matrices.push(); - matrices.translate(dX, 0, 0); - - TextRenderer.Drawer drawer = (TextRenderer.Drawer) textRenderer.prepare(line.asOrderedText(), 0, i * 12, entity.color, entity.shadow, 0); - - TextRenderer.GlyphDrawer glyphDrawer = TextRenderer.GlyphDrawer.drawing( - vertexConsumers, - matrices.peek().getPositionMatrix(), - TextLayerType.NORMAL, - // TODO: use the light param and add a toggle to make it glow (use LightmapTextureManager.MAX_LIGHT_COORDINATE) - LightmapTextureManager.MAX_LIGHT_COORDINATE - ); - - // Yep, we're back to that hack again. - if (entity.backgroundColor != 0) { - BakedGlyph rectangleBakedGlyph = ((TextRendererAccessor) textRenderer) - .invokeGetFontStorage(Style.DEFAULT_FONT_ID) - .getRectangleBakedGlyph(); - - final BakedGlyph.Rectangle rect = new BakedGlyph.Rectangle( - -4, i * 12 - 2f, - (float) width + 4, (i + 1) * 12 - 2f, - -0.01F, entity.backgroundColor); - - glyphDrawer.drawRectangle(rectangleBakedGlyph, rect); - } - - drawer.draw(glyphDrawer); - - matrices.pop(); + public void submit(TextRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + if (state.shouldRenderPlaceholder) { + BlockEntityRenderUtil.renderPlaceholderWithBlockRotation(state, state.rotation16, ITEM_TEXTURE, 1.0F, poseStack, submitNodeCollector, state.zOffset == TextBlockEntity.ZOffset.CENTER ? 0.01F : state.zOffset == TextBlockEntity.ZOffset.FRONT ? 0.4F : -0.4F); } - - matrices.pop(); } +// FIXME 26.1 + // @Override +// public boolean shouldBake(TextBlockEntity entity) { +// return !entity.lines.isEmpty(); +// } +// +// @Override +// public void renderUnbaked(TextBlockEntity entity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, Vec3 cameraPos) { +// Entity camera = Minecraft.getInstance().getCameraEntity(); +// if (camera != null && entity.viewDistance >= 0) { +// double dx = camera.getX() - (entity.getBlockPos().getX() + 0.5); +// double dy = camera.getY() - (entity.getBlockPos().getY() + 0.5); +// double dz = camera.getZ() - (entity.getBlockPos().getZ() + 0.5); +// +// if ((dx * dx + dy * dy + dz * dz) > (entity.viewDistance * entity.viewDistance)) { +// if (!wasOutOfRange) { +// entity.renderDirty = true; +// wasOutOfRange = true; +// } +// } else { +// if (wasOutOfRange) { +// entity.renderDirty = true; +// } +// +// wasOutOfRange = false; +// } +// } +// +// if (entity.renderDirty) { +// entity.renderDirty = false; +// BakedBlockEntityRenderer.Manager.markForRebuild(entity.getBlockPos()); +// } +// +// if (entity.getLevel() == null || entity.getLevel().getBlockState(entity.getBlockPos()).isAir()) return; +// } +// +// @Override +// public void renderBaked(TextBlockEntity entity, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay) { +// Entity camera = Minecraft.getInstance().getCameraEntity(); +// if (camera != null && entity.viewDistance >= 0) { +// double dx = camera.getX() - (entity.getBlockPos().getX() + 0.5); +// double dy = camera.getY() - (entity.getBlockPos().getY() + 0.5); +// double dz = camera.getZ() - (entity.getBlockPos().getZ() + 0.5); +// +// if ((dx * dx + dy * dy + dz * dz) > (entity.viewDistance * entity.viewDistance)) { +// if (!wasOutOfRange) { +// entity.renderDirty = true; +// wasOutOfRange = true; +// } +// +// return; +// } else { +// if (wasOutOfRange) { +// entity.renderDirty = true; +// } +// +// wasOutOfRange = false; +// } +// } +// +// matrices.pushPose(); +// matrices.translate(0.5D, 0.5D, 0.5D); +// +// float rotation = -(entity.getBlockState().getValue(BlockStateProperties.ROTATION_16) * 360) / 16.0F; +// matrices.mulPose(Axis.YP.rotationDegrees(rotation)); +// +// switch (entity.zOffset) { +// case FRONT -> matrices.translate(0D, 0D, 0.4D); +// case BACK -> matrices.translate(0D, 0D, -0.4D); +// } +// +// float scale = 0.010416667F * entity.scale; +// matrices.scale(scale, -scale, scale); +// Font textRenderer = this.context.getFont(); +// +// double maxLength = 0; +// double minLength = Double.MAX_VALUE; +// for (int i = 0; i < entity.lines.size(); ++i) { +// maxLength = Math.max(maxLength, textRenderer.width(entity.lines.get(i))); +// minLength = Math.min(minLength, textRenderer.width(entity.lines.get(i))); +// } +// +// matrices.translate(0, -((entity.lines.size() - 0.25) * 12) / 2D, 0D); +// for (int i = 0; i < entity.lines.size(); ++i) { +// Component line = entity.lines.get(i); +// double width = textRenderer.width(line); +// if (width == 0) continue; +// +// double dX = switch (entity.textAlignment) { +// case LEFT -> -maxLength / 2D; +// case CENTER -> (maxLength - width) / 2D - maxLength / 2D; +// case CENTER_LEFT -> -(50D / entity.scale) - (width / 2D); +// case CENTER_RIGHT -> (50D / entity.scale) - (width / 2D); +// case RIGHT -> maxLength - width - maxLength / 2D; +// }; +// +// matrices.pushPose(); +// matrices.translate(dX, 0, 0); +// +// Font.PreparedTextBuilder drawer = (Font.PreparedTextBuilder) textRenderer.prepareText(line.getVisualOrderText(), 0, i * 12, entity.color, entity.shadow, 0); +// +// Font.GlyphVisitor glyphDrawer = Font.GlyphVisitor.forMultiBufferSource( +// vertexConsumers, +// matrices.last().pose(), +// DisplayMode.NORMAL, +// // TODO: use the light param and add a toggle to make it glow (use LightmapTextureManager.MAX_LIGHT_COORDINATE) +// Lightmap.FULL_BRIGHT +// ); +// +// // Yep, we're back to that hack again. +// if (entity.backgroundColor != 0) { +// BakedGlyph rectangleBakedGlyph = ((FontAccessor) textRenderer) +// .invokeGetFontStorage(Style.DEFAULT_FONT) +// .whiteGlyph(); +// +// final BakedGlyph.Effect rect = new BakedGlyph.Effect( +// -4, i * 12 - 2f, +// (float) width + 4, (i + 1) * 12 - 2f, +// -0.01F, entity.backgroundColor); +// +// glyphDrawer.acceptEffect(rectangleBakedGlyph, rect); +// } +// +// drawer.visit(glyphDrawer); +// +// matrices.popPose(); +// } +// +// matrices.popPose(); +// } + } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/item/ItemHandRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/item/ItemHandRenderer.java index b41ef0d8..1268e066 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/item/ItemHandRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/item/ItemHandRenderer.java @@ -1,13 +1,13 @@ package dev.hephaestus.glowcase.client.render.item; import com.google.common.collect.Maps; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; +import com.mojang.blaze3d.vertex.PoseStack; import org.jetbrains.annotations.Nullable; import java.util.Map; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; /** * Called when the item is being held in hand. @@ -16,7 +16,7 @@ public abstract class ItemHandRenderer { /** * Called on each frame when the player is holding the given stack. */ - public abstract void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, ItemStack stack); + public abstract void render(PoseStack matrices, MultiBufferSource vertexConsumers, int light, ItemStack stack); /** * Whenever the item should be rendered or not. @@ -40,7 +40,7 @@ public static void register(Item item, ItemHandRenderer factory) { */ public static @Nullable ItemHandRenderer getRenderer(ItemStack stack) { for (Item item : RENDERER.keySet()) - if (stack.isOf(item)) + if (stack.is(item)) return RENDERER.get(item); return null; diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/item/NoteItemHandRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/item/NoteItemHandRenderer.java index 9f395774..d5635925 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/item/NoteItemHandRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/item/NoteItemHandRenderer.java @@ -1,25 +1,25 @@ package dev.hephaestus.glowcase.client.render.item; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.client.gui.screen.ingame.NoteEditScreen; import dev.hephaestus.glowcase.client.util.NoteTextColorResource; import dev.hephaestus.glowcase.item.component.NoteComponent; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemStack; -import net.minecraft.text.StringVisitable; -import net.minecraft.text.Text; -import net.minecraft.util.Colors; -import net.minecraft.util.Identifier; -import net.minecraft.util.Language; -import net.minecraft.util.math.RotationAxis; +import net.minecraft.client.renderer.rendertype.RenderTypes; import org.joml.Matrix4f; import java.util.List; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.locale.Language; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FormattedText; +import net.minecraft.resources.Identifier; +import net.minecraft.util.CommonColors; +import net.minecraft.world.item.ItemStack; public class NoteItemHandRenderer extends ItemHandRenderer { private static final Identifier NOTE_TEXTURE = Glowcase.id("textures/gui/note.png"); @@ -32,18 +32,18 @@ public class NoteItemHandRenderer extends ItemHandRenderer { private static final int TXT_X_PADDING = 15 * 2; @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, ItemStack stack) { - matrices.push(); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180.0F)); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180.0F)); + public void render(PoseStack matrices, MultiBufferSource vertexConsumers, int light, ItemStack stack) { + matrices.pushPose(); + matrices.mulPose(Axis.YP.rotationDegrees(180.0F)); + matrices.mulPose(Axis.ZP.rotationDegrees(180.0F)); matrices.scale(0.38F, 0.38F, 0.38F); matrices.translate(-0.5F, -0.5F, 0.0F); matrices.scale(0.0078125F, 0.0078125F, 0.0078125F); // Render background - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getText(NOTE_TEXTURE)); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderTypes.text(NOTE_TEXTURE)); + Matrix4f matrix4f = matrices.last().pose(); { float max_x = 1.0F / BG_SIZE * BG_WIDTH; @@ -60,49 +60,49 @@ public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, float y1 = begin + ((Math.abs(begin) + end) - height) + y_off; end += y_off; - vertexConsumer.vertex(matrix4f, x_off + begin, end, 0.0F).color(Colors.WHITE).texture(0.0F, max_y).light(light); - vertexConsumer.vertex(matrix4f, x_off + end, end, 0.0F).color(Colors.WHITE).texture(max_x, max_y).light(light); - vertexConsumer.vertex(matrix4f, x_off + end, y1, 0.0F).color(Colors.WHITE).texture(max_x, 0.0F).light(light); - vertexConsumer.vertex(matrix4f, x_off + begin, y1, 0.0F).color(Colors.WHITE).texture(0.0F, 0.0F).light(light); + vertexConsumer.addVertex(matrix4f, x_off + begin, end, 0.0F).setColor(CommonColors.WHITE).setUv(0.0F, max_y).setLight(light); + vertexConsumer.addVertex(matrix4f, x_off + end, end, 0.0F).setColor(CommonColors.WHITE).setUv(max_x, max_y).setLight(light); + vertexConsumer.addVertex(matrix4f, x_off + end, y1, 0.0F).setColor(CommonColors.WHITE).setUv(max_x, 0.0F).setLight(light); + vertexConsumer.addVertex(matrix4f, x_off + begin, y1, 0.0F).setColor(CommonColors.WHITE).setUv(0.0F, 0.0F).setLight(light); } // Render Text NoteComponent noteComponent = stack.get(Glowcase.NOTE_COMPONENT.get()); if (noteComponent == null) { - matrices.pop(); + matrices.popPose(); return; } float off_x = -7F; float off_y = 63F; - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + Font textRenderer = Minecraft.getInstance().font; matrices.translate(off_x, off_y, -.01f); matrices.scale(0.67f, 0.67f, 1f); float width = BG_WIDTH - TXT_X_PADDING; - List lines = noteComponent.lines(); + List lines = noteComponent.lines(); for (int i=0; i 0; - case CENTER -> width/2f - textRenderer.getWidth(text)/2f - 1; // We don't ask why the -1 is there - case RIGHT -> BG_WIDTH - TXT_X_PADDING - textRenderer.getWidth(text); + case CENTER -> width/2f - textRenderer.width(text)/2f - 1; // We don't ask why the -1 is there + case RIGHT -> BG_WIDTH - TXT_X_PADDING - textRenderer.width(text); }; - textRenderer.draw(Language.getInstance().reorder(text), x, textRenderer.fontHeight * i, NoteTextColorResource.TXT_COLOR, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, light); + textRenderer.drawInBatch(Language.getInstance().getVisualOrder(text), x, textRenderer.lineHeight * i, NoteTextColorResource.TXT_COLOR, false, matrices.last().pose(), vertexConsumers, Font.DisplayMode.NORMAL, 0, light); } - matrices.pop(); + matrices.popPose(); } @Override public boolean visible(ItemStack stack) { - return (stack.contains(Glowcase.NOTE_COMPONENT.get())); + return (stack.has(Glowcase.NOTE_COMPONENT.get())); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/item/TabletItemHandRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/item/TabletItemHandRenderer.java index 137573db..d08b5386 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/item/TabletItemHandRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/item/TabletItemHandRenderer.java @@ -1,53 +1,53 @@ package dev.hephaestus.glowcase.client.render.item; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.datafixers.util.Pair; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.client.GlowcaseClient; import dev.hephaestus.glowcase.client.ScreenImageCache; import dev.hephaestus.glowcase.client.render.block.entity.ScreenBlockEntityRenderer; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Colors; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; +import net.minecraft.client.renderer.rendertype.RenderTypes; import org.joml.Matrix4f; import java.util.List; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.Identifier; +import net.minecraft.util.CommonColors; +import net.minecraft.world.item.ItemStack; public class TabletItemHandRenderer extends ItemHandRenderer { private static final Identifier TABLET_TEXTURE = Glowcase.id("textures/gui/tablet_hand.png"); @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, ItemStack stack) { - matrices.push(); + public void render(PoseStack matrices, MultiBufferSource vertexConsumers, int light, ItemStack stack) { + matrices.pushPose(); //RenderSystem.enableBlend(); // Render background - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180.0F)); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180.0F)); + matrices.mulPose(Axis.YP.rotationDegrees(180.0F)); + matrices.mulPose(Axis.ZP.rotationDegrees(180.0F)); matrices.scale(0.38F, 0.38F, 0.38F); matrices.translate(-0.5F, -0.5F, 0.0F); matrices.scale(0.0078125F, 0.0078125F, 0.0078125F); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getText(TABLET_TEXTURE)); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderTypes.text(TABLET_TEXTURE)); + Matrix4f matrix4f = matrices.last().pose(); - vertexConsumer.vertex(matrix4f, -7.0F, 135.0F, 0.0F).color(Colors.WHITE).texture(0.0F, 1.0F).light(light); - vertexConsumer.vertex(matrix4f, 135.0F, 135.0F, 0.0F).color(Colors.WHITE).texture(1.0F, 1.0F).light(light); - vertexConsumer.vertex(matrix4f, 135.0F, -7.0F, 0.0F).color(Colors.WHITE).texture(1.0F, 0.0F).light(light); - vertexConsumer.vertex(matrix4f, -7.0F, -7.0F, 0.0F).color(Colors.WHITE).texture(0.0F, 0.0F).light(light); + vertexConsumer.addVertex(matrix4f, -7.0F, 135.0F, 0.0F).setColor(CommonColors.WHITE).setUv(0.0F, 1.0F).setLight(light); + vertexConsumer.addVertex(matrix4f, 135.0F, 135.0F, 0.0F).setColor(CommonColors.WHITE).setUv(1.0F, 1.0F).setLight(light); + vertexConsumer.addVertex(matrix4f, 135.0F, -7.0F, 0.0F).setColor(CommonColors.WHITE).setUv(1.0F, 0.0F).setLight(light); + vertexConsumer.addVertex(matrix4f, -7.0F, -7.0F, 0.0F).setColor(CommonColors.WHITE).setUv(0.0F, 0.0F).setLight(light); - if (!stack.contains(Glowcase.SLIDESHOW_COMPONENT.get()) || !stack.contains(Glowcase.CURRENT_SLIDE_COMPONENT.get())) { - matrices.pop(); + if (!stack.has(Glowcase.SLIDESHOW_COMPONENT.get()) || !stack.has(Glowcase.CURRENT_SLIDE_COMPONENT.get())) { + matrices.popPose(); return; } @@ -55,18 +55,18 @@ public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, Integer index = stack.getOrDefault(Glowcase.CURRENT_SLIDE_COMPONENT.get(), 0); if (slideshow == null || index >= slideshow.size()) { - matrices.pop(); + matrices.popPose(); return; } // Render current slide text { - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - MutableText literal = Text.translatable("gui.glowcase.progress", index + 1, slideshow.size()); + Font textRenderer = Minecraft.getInstance().font; + MutableComponent literal = Component.translatable("gui.glowcase.progress", index + 1, slideshow.size()); float font_scale = 1f; - float font_width = textRenderer.getWidth(literal); + float font_width = textRenderer.width(literal); float font_max_width = 142f/64f*14f; if (font_width >= font_max_width) { font_scale = font_max_width / font_width; @@ -77,7 +77,7 @@ public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, matrices.translate(off_x, off_y, -.01f); matrices.scale(font_scale, font_scale, 1f); - textRenderer.draw(literal, 0, 0, 0xFFFFFFFF, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.NORMAL, 0, light); + textRenderer.drawInBatch(literal, 0, 0, 0xFFFFFFFF, false, matrices.last().pose(), vertexConsumers, Font.DisplayMode.NORMAL, 0, light); matrices.translate(-off_x, -off_y, .01f); matrices.scale(1f/font_scale, 1f/font_scale, 1f); } @@ -89,12 +89,12 @@ public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, ScreenImageCache.ScreenTexture image = GlowcaseClient.screenImageCache.getImage(url, null); Identifier texture = image.getTexture().getSecond(); if (texture == null) { - matrices.pop(); + matrices.popPose(); return; } - vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getText(texture)); - matrix4f = matrices.peek().getPositionMatrix(); + vertexConsumer = vertexConsumers.getBuffer(RenderTypes.text(texture)); + matrix4f = matrices.last().pose(); float pixel = 142f/64f; @@ -113,11 +113,11 @@ public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, y1 = -scaled_height / 2f; y2 = scaled_height / 2f; - vertexConsumer.vertex(matrix4f, 64+x1, 64+y1, -0.01F).color(Colors.WHITE).texture(0f, 0f).light(light); - vertexConsumer.vertex(matrix4f, 64+x1, 64+y2, -0.01F).color(Colors.WHITE).texture(0f, 1f).light(light); - vertexConsumer.vertex(matrix4f, 64+x2, 64+y2, -0.01F).color(Colors.WHITE).texture(1f, 1f).light(light); - vertexConsumer.vertex(matrix4f, 64+x2, 64+y1, -0.01F).color(Colors.WHITE).texture(1f, 0f).light(light); + vertexConsumer.addVertex(matrix4f, 64+x1, 64+y1, -0.01F).setColor(CommonColors.WHITE).setUv(0f, 0f).setLight(light); + vertexConsumer.addVertex(matrix4f, 64+x1, 64+y2, -0.01F).setColor(CommonColors.WHITE).setUv(0f, 1f).setLight(light); + vertexConsumer.addVertex(matrix4f, 64+x2, 64+y2, -0.01F).setColor(CommonColors.WHITE).setUv(1f, 1f).setLight(light); + vertexConsumer.addVertex(matrix4f, 64+x2, 64+y1, -0.01F).setColor(CommonColors.WHITE).setUv(1f, 0f).setLight(light); - matrices.pop(); + matrices.popPose(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/item/tint/GlowcaseTintSource.java b/src/main/java/dev/hephaestus/glowcase/client/render/item/tint/GlowcaseTintSource.java index 8733fdc6..da8392a8 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/item/tint/GlowcaseTintSource.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/item/tint/GlowcaseTintSource.java @@ -4,35 +4,37 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.render.item.tint.TintSource; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.NbtComponent; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.util.dynamic.Codecs; +import net.minecraft.client.color.item.ItemTintSource; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.component.TypedEntityData; +import net.minecraft.world.level.block.entity.BlockEntityType; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) -public record GlowcaseTintSource(int defaultColor) implements TintSource { +public record GlowcaseTintSource(int defaultColor) implements ItemTintSource { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( - instance -> instance.group(Codecs.RGB.fieldOf("default").forGetter(GlowcaseTintSource::defaultColor)).apply(instance, GlowcaseTintSource::new) + instance -> instance.group(ExtraCodecs.RGB_COLOR_CODEC.fieldOf("default").forGetter(GlowcaseTintSource::defaultColor)).apply(instance, GlowcaseTintSource::new) ); @Override - public int getTint(ItemStack stack, @Nullable ClientWorld world, @Nullable LivingEntity user) { - NbtComponent component = stack.get(DataComponentTypes.BLOCK_ENTITY_DATA); + public int calculate(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity user) { + TypedEntityData> component = stack.get(DataComponents.BLOCK_ENTITY_DATA); if (component == null) return defaultColor; - NbtCompound nbt = component.copyNbt(); - int color = nbt.getInt("color", 0); + CompoundTag nbt = component.getUnsafe(); + int color = nbt.getIntOr("color", 0); if (color != 0 && color != defaultColor) return color; return 0xFFAA00AA; } @Override - public MapCodec getCodec() { + public MapCodec type() { return CODEC; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/util/BlockEntityRenderUtil.java b/src/main/java/dev/hephaestus/glowcase/client/util/BlockEntityRenderUtil.java index eefb6eb0..d88539fd 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/util/BlockEntityRenderUtil.java +++ b/src/main/java/dev/hephaestus/glowcase/client/util/BlockEntityRenderUtil.java @@ -1,28 +1,25 @@ package dev.hephaestus.glowcase.client.util; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.Camera; -import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.state.property.Properties; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec2f; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; +import net.minecraft.client.renderer.rendertype.RenderTypes; +import net.minecraft.client.renderer.state.CameraRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.Identifier; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec2; import org.joml.Quaternionf; import org.joml.Vector3f; -import java.util.stream.IntStream; - public class BlockEntityRenderUtil { private static final Vector3f[] placeholderVertices = new Vector3f[]{ new Vector3f(-0.5F, -0.5F, 0.0F), @@ -31,57 +28,75 @@ public class BlockEntityRenderUtil { new Vector3f(-0.5F, 0.5F, 0.0F) }; - public static void renderPlaceholder(BlockEntity entity, Identifier texture, float scale, Quaternionf rotation, MatrixStack matrices, VertexConsumerProvider vertexConsumers, float zOffset) { - matrices.push(); - matrices.translate(0.5, 0.5, 0.5); - matrices.multiply(rotation); - matrices.translate(0, 0, zOffset); - matrices.scale(scale, scale, scale); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getEntityCutout(texture)); - renderPlaceholderFace(matrices.peek(), vertexConsumer, entity.getPos()); - renderPlaceholderBackFace(matrices.peek(), vertexConsumer, entity.getPos()); - matrices.pop(); + public static void renderPlaceholder(BlockEntityRenderState state, Identifier texture, float scale, Quaternionf rotation, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, float zOffset) { + poseStack.pushPose(); + poseStack.translate(0.5, 0.5, 0.5); + poseStack.mulPose(rotation); + poseStack.translate(0, 0, zOffset); + poseStack.scale(scale, scale, scale); + submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.entityCutoutCull(texture), new SubmitNodeCollector.CustomGeometryRenderer() { + @Override + public void render(PoseStack.Pose pose, VertexConsumer buffer) { + renderPlaceholderBackFace(pose, buffer, state.blockPos); + renderPlaceholderFace(pose, buffer, state.blockPos); + } + }); + poseStack.popPose(); } - public static void renderBillboardPlaceholder(BlockEntity entity, Identifier texture, float scale, MatrixStack matrices, VertexConsumerProvider vertexConsumers, Camera camera) { - matrices.push(); - matrices.translate(0.5, 0.5, 0.5); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180.0F - camera.getYaw())); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-camera.getPitch())); - matrices.scale(scale, scale, scale); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getEntityCutout(texture)); - renderPlaceholderFace(matrices.peek(), vertexConsumer, entity.getPos()); - matrices.pop(); + public static void renderBillboardPlaceholder(BlockEntityRenderState entity, Identifier texture, float scale, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) { + poseStack.pushPose(); + poseStack.translate(0.5, 0.5, 0.5); + poseStack.mulPose(Axis.YP.rotationDegrees(180.0F - camera.yRot)); + poseStack.mulPose(Axis.XP.rotationDegrees(-camera.xRot)); + poseStack.scale(scale, scale, scale); + submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.entityCutout(texture), new SubmitNodeCollector.CustomGeometryRenderer() { + @Override + public void render(PoseStack.Pose pose, VertexConsumer buffer) { + renderPlaceholderFace(pose, buffer, entity.blockPos); + } + }); + poseStack.popPose(); } - public static void renderTrackingPlaceholder(BlockEntity entity, Identifier texture, float scale, MatrixStack matrices, VertexConsumerProvider vertexConsumers, Entity camera, float tickDelta) { - matrices.push(); - matrices.translate(0.5, 0.5, 0.5); - Vec2f tracking = getTracking(camera, entity.getPos(), tickDelta); + public static void renderTrackingPlaceholder(BlockEntityRenderState state, Identifier texture, float scale, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, Entity camera, float tickDelta) { + poseStack.pushPose(); + poseStack.translate(0.5, 0.5, 0.5); + Vec2 tracking = getTracking(camera, state.blockPos, tickDelta); float pitch = tracking.x; float yaw = tracking.y; - matrices.multiply(RotationAxis.POSITIVE_Y.rotation((float) (Math.PI + yaw))); - matrices.multiply(RotationAxis.POSITIVE_X.rotation(-pitch)); - matrices.scale(scale, scale, scale); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getEntityCutout(texture)); - renderPlaceholderFace(matrices.peek(), vertexConsumer, entity.getPos()); - matrices.pop(); + poseStack.mulPose(Axis.YP.rotation((float) (Math.PI + yaw))); + poseStack.mulPose(Axis.XP.rotation(-pitch)); + poseStack.scale(scale, scale, scale); + submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.entityCutout(texture), new SubmitNodeCollector.CustomGeometryRenderer() { + @Override + public void render(PoseStack.Pose pose, VertexConsumer buffer) { + renderPlaceholderFace(pose, buffer, state.blockPos); + } + }); + poseStack.popPose(); } - public static void renderPlaceholderWithBlockRotation(BlockEntity entity, Identifier texture, float scale, MatrixStack matrices, VertexConsumerProvider vertexConsumers, float zOffset) { - renderPlaceholder(entity, texture, scale, RotationAxis.POSITIVE_Y.rotationDegrees(-(entity.getCachedState().get(Properties.ROTATION) * 360) / 16.0F), matrices, vertexConsumers, zOffset); + public static void renderPlaceholderWithBlockRotation(BlockEntityRenderState entity, int rotation16, Identifier texture, + float scale, PoseStack matrices, SubmitNodeCollector vertexConsumers, float zOffset) { + renderPlaceholder(entity, texture, scale, + Axis.YP.rotationDegrees(-(rotation16 * 360) / 16.0F), + matrices, vertexConsumers, zOffset); } - public static void renderPlaceholderWithBlockRotation(BlockEntity entity, Identifier texture, float scale, MatrixStack matrices, VertexConsumerProvider vertexConsumers) { - renderPlaceholderWithBlockRotation(entity, texture, scale, matrices, vertexConsumers, 0F); + public static void renderPlaceholderWithBlockRotation(BlockEntityRenderState entity, int rotation16, Identifier texture, + float scale, PoseStack matrices, SubmitNodeCollector vertexConsumers) { + renderPlaceholderWithBlockRotation(entity, rotation16, texture, scale, matrices, vertexConsumers, 0F); } - public static void renderCenteredPlaceholder(BlockEntity entity, Identifier texture, float scale, Quaternionf rotation, MatrixStack matrices, VertexConsumerProvider vertexConsumers) { - renderPlaceholder(entity, texture, scale, rotation, matrices, vertexConsumers, 0F); + public static void renderCenteredPlaceholder(BlockEntityRenderState entity, Identifier texture, + float scale, Quaternionf rotation, PoseStack matrices, SubmitNodeCollector submitNodeCollector) { + renderPlaceholder(entity, texture, scale, rotation, matrices, submitNodeCollector, 0F); } - public static void renderFacingPlaceholder(BlockEntity entity, Identifier texture, float scale, MatrixStack matrices, VertexConsumerProvider vertexConsumers) { - renderPlaceholder(entity, texture, scale, entity.getCachedState().get(Properties.FACING).getRotationQuaternion().mul(RotationAxis.POSITIVE_X.rotationDegrees(-90.0F)), matrices, vertexConsumers, -0.4F); + public static void renderFacingPlaceholder(BlockEntityRenderState entity, Direction facing, Identifier texture, + float scale, PoseStack matrices, SubmitNodeCollector submitNodeCollector) { + renderPlaceholder(entity, texture, scale, facing.getRotation().mul(Axis.XP.rotationDegrees(-90.0F)), matrices, submitNodeCollector, -0.4F); } public static boolean shouldRenderPlaceholder(BlockPos pos) { @@ -89,31 +104,31 @@ public static boolean shouldRenderPlaceholder(BlockPos pos) { } public static boolean shouldRenderPlaceholder(BlockPos pos, boolean disappearWhenFaced) { - return MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().player.isHolding(stack -> stack.isIn(Glowcase.ITEM_TAG)) && (!disappearWhenFaced || !(MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult bhr && bhr.getBlockPos().equals(pos))); + return Minecraft.getInstance().player != null && Minecraft.getInstance().player.isHolding(stack -> stack.is(Glowcase.ITEM_TAG)) && (!disappearWhenFaced || !(Minecraft.getInstance().hitResult instanceof BlockHitResult bhr && bhr.getBlockPos().equals(pos))); } - public static Vec2f getTracking(Entity camera, BlockPos pos, float delta) { - double d = pos.getX() - camera.getLerpedPos(delta).x + 0.5; + public static Vec2 getTracking(Entity camera, BlockPos pos, float delta) { + double d = pos.getX() - camera.getPosition(delta).x + 0.5; double e = pos.getY() - camera.getEyeY() + 0.5; - double f = pos.getZ() - camera.getLerpedPos(delta).z + 0.5; - double g = MathHelper.sqrt((float) (d * d + f * f)); + double f = pos.getZ() - camera.getPosition(delta).z + 0.5; + double g = Mth.sqrt((float) (d * d + f * f)); - float pitch = (float) ((-MathHelper.atan2(e, g))); - float yaw = (float) (-MathHelper.atan2(f, d) + Math.PI / 2); + float pitch = (float) ((-Mth.atan2(e, g))); + float yaw = (float) (-Mth.atan2(f, d) + Math.PI / 2); - return new Vec2f(pitch, yaw); + return new Vec2(pitch, yaw); } - private static void renderPlaceholderFace(MatrixStack.Entry entry, VertexConsumer vertexConsumer, BlockPos pos) { - int color = MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult bhr && bhr.getBlockPos().equals(pos) ? 0x808080 : 0xFFFFFF; + private static void renderPlaceholderFace(PoseStack.Pose entry, VertexConsumer vertexConsumer, BlockPos pos) { + int color = Minecraft.getInstance().hitResult instanceof BlockHitResult bhr && bhr.getBlockPos().equals(pos) ? 0x808080 : 0xFFFFFF; placeholderVertex(entry, vertexConsumer, placeholderVertices[0], 0, 1, color); placeholderVertex(entry, vertexConsumer, placeholderVertices[1], 1, 1, color); placeholderVertex(entry, vertexConsumer, placeholderVertices[2], 1, 0, color); placeholderVertex(entry, vertexConsumer, placeholderVertices[3], 0, 0, color); } - private static void renderPlaceholderBackFace(MatrixStack.Entry entry, VertexConsumer vertexConsumer, BlockPos pos) { - int color = MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult bhr && bhr.getBlockPos().equals(pos) ? 0x404040 : 0x808080; + private static void renderPlaceholderBackFace(PoseStack.Pose entry, VertexConsumer vertexConsumer, BlockPos pos) { + int color = Minecraft.getInstance().hitResult instanceof BlockHitResult bhr && bhr.getBlockPos().equals(pos) ? 0x404040 : 0x808080; placeholderVertex(entry, vertexConsumer, placeholderVertices[3], 0, 0, color); placeholderVertex(entry, vertexConsumer, placeholderVertices[2], 1, 0, color); placeholderVertex(entry, vertexConsumer, placeholderVertices[1], 1, 1, color); @@ -121,12 +136,12 @@ private static void renderPlaceholderBackFace(MatrixStack.Entry entry, VertexCon } private static void placeholderVertex( - MatrixStack.Entry matrix, VertexConsumer vertexConsumer, Vector3f vertex, float u, float v, int color) { - vertexConsumer.vertex(matrix, vertex.x(), vertex.y(), vertex.z()) - .color(color) - .texture(u, v) - .overlay(OverlayTexture.DEFAULT_UV) - .light(LightmapTextureManager.MAX_LIGHT_COORDINATE) - .normal(0, 1, 0); + PoseStack.Pose matrix, VertexConsumer vertexConsumer, Vector3f vertex, float u, float v, int color) { + vertexConsumer.addVertex(matrix, vertex.x(), vertex.y(), vertex.z()) + .setColor(color) + .setUv(u, v) + .setOverlay(OverlayTexture.NO_OVERLAY) + .setLight(0xFF) + .setNormal(0, 1, 0); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/util/ColorUtil.java b/src/main/java/dev/hephaestus/glowcase/client/util/ColorUtil.java index c9fc0e30..aceddb11 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/util/ColorUtil.java +++ b/src/main/java/dev/hephaestus/glowcase/client/util/ColorUtil.java @@ -1,7 +1,7 @@ package dev.hephaestus.glowcase.client.util; import com.mojang.serialization.DataResult; -import net.minecraft.util.Formatting; +import net.minecraft.ChatFormatting; /** * @author Ampflower @@ -41,12 +41,12 @@ public static DataResult parse(String string, int reference) { return DataResult.error(() -> "Not a number: " + string); } } else { - final Formatting formatting = Formatting.byName(string); + final ChatFormatting formatting = ChatFormatting.getByName(string); if (formatting == null || !formatting.isColor()) { return DataResult.error(() -> "Unknown color: " + string); } - int rgb = formatting.getColorValue() & COLOR_MASK; + int rgb = formatting.getColor() & COLOR_MASK; int a = reference & ALPHA_MASK; return DataResult.success(a | rgb); diff --git a/src/main/java/dev/hephaestus/glowcase/client/util/ConfigLinkClientUtil.java b/src/main/java/dev/hephaestus/glowcase/client/util/ConfigLinkClientUtil.java index 468c008a..989631bc 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/util/ConfigLinkClientUtil.java +++ b/src/main/java/dev/hephaestus/glowcase/client/util/ConfigLinkClientUtil.java @@ -6,11 +6,11 @@ import net.fabricmc.api.Environment; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.NoticeScreen; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.screen.ScreenTexts; -import net.minecraft.text.Text; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.AlertScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; import java.util.Optional; @@ -22,10 +22,10 @@ public final class ConfigLinkClientUtil { private static final boolean modmenuAvailable = FabricLoader.getInstance().isModLoaded("modmenu"); - private static final Text glowcase = Text.translatable("block.glowcase.config_link_block"); - private static final Text missingModmenu = Text.translatable("gui.glowcase.config_link.missing.modmenu"); + private static final Component glowcase = Component.translatable("block.glowcase.config_link_block"); + private static final Component missingModmenu = Component.translatable("gui.glowcase.config_link.missing.modmenu"); - public static Screen getConfigScreen(MinecraftClient client, String link) { + public static Screen getConfigScreen(Minecraft client, String link) { Screen screen = getModScreen(client, link); if (screen != null) { @@ -36,7 +36,7 @@ public static Screen getConfigScreen(MinecraftClient client, String link) { } @Nullable - public static Screen getModScreen(MinecraftClient client, String link) { + public static Screen getModScreen(Minecraft client, String link) { String id = ModSupportUtil.getModId(link); if (id == null) { @@ -60,23 +60,23 @@ public static Screen getModScreen(MinecraftClient client, String link) { .orElseGet(() -> modUnavailable(client, id)); } - private static Screen modScreenUnavailable(MinecraftClient client, String modName) { - return notice(client, glowcase, Text.translatable("gui.glowcase.config_link.missing.mod_screen", modName)); + private static Screen modScreenUnavailable(Minecraft client, String modName) { + return notice(client, glowcase, Component.translatable("gui.glowcase.config_link.missing.mod_screen", modName)); } - private static Screen modUnavailable(MinecraftClient client, String modId) { - return notice(client, glowcase, Text.translatable("gui.glowcase.config_link.missing.mod", modId)); + private static Screen modUnavailable(Minecraft client, String modId) { + return notice(client, glowcase, Component.translatable("gui.glowcase.config_link.missing.mod", modId)); } - private static Screen modmenuUnavailable(MinecraftClient client) { + private static Screen modmenuUnavailable(Minecraft client) { return notice(client, glowcase, missingModmenu); } - private static Screen notImplemented(MinecraftClient client, String link) { - return notice(client, glowcase, Text.translatable("gui.glowcase.config_link.missing.link", link)); + private static Screen notImplemented(Minecraft client, String link) { + return notice(client, glowcase, Component.translatable("gui.glowcase.config_link.missing.link", link)); } - private static Screen notice(MinecraftClient client, Text title, Text notice) { - return new NoticeScreen(() -> client.setScreen(null), title, notice, ScreenTexts.OK, true); + private static Screen notice(Minecraft client, Component title, Component notice) { + return new AlertScreen(() -> client.setScreen(null), title, notice, CommonComponents.GUI_OK, true); } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/util/EmiClientUtils.java b/src/main/java/dev/hephaestus/glowcase/client/util/EmiClientUtils.java index d1b8a769..3e6708e3 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/util/EmiClientUtils.java +++ b/src/main/java/dev/hephaestus/glowcase/client/util/EmiClientUtils.java @@ -6,10 +6,9 @@ //import dev.emi.emi.widget.RecipeBackground; import dev.hephaestus.glowcase.util.EmiUtils; import dev.hephaestus.glowcase.util.RequiresEmiLoaded; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.util.Identifier; - import java.util.concurrent.atomic.AtomicReference; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.resources.Identifier; public class EmiClientUtils { public static void displayRecipe(Identifier recipeId) { @@ -47,7 +46,7 @@ public static void updateWidgetHolder(String recipeId, AtomicReference modIconCache = new HashMap<>(); + private static final Map modIconCache = new HashMap<>(); - public static NativeImageBackedTexture createIcon(ModContainer iconSource, String iconPath) { + public static DynamicTexture createIcon(ModContainer iconSource, String iconPath) { try { Path path = iconSource.getPath(iconPath); - NativeImageBackedTexture cachedIcon = modIconCache.get(path); + DynamicTexture cachedIcon = modIconCache.get(path); if (cachedIcon != null) { return cachedIcon; } @@ -35,7 +35,7 @@ public static NativeImageBackedTexture createIcon(ModContainer iconSource, Strin try (InputStream inputStream = Files.newInputStream(path)) { NativeImage image = NativeImage.read(Objects.requireNonNull(inputStream)); Validate.validState(image.getHeight() == image.getWidth(), "Must be square icon"); - NativeImageBackedTexture tex = new NativeImageBackedTexture(() -> Integer.toHexString(image.hashCode()), image); + DynamicTexture tex = new DynamicTexture(() -> Integer.toHexString(image.hashCode()), image); modIconCache.put(path, tex); return tex; } @@ -58,7 +58,7 @@ public static NativeImageBackedTexture createIcon(ModContainer iconSource, Strin } } - public static NativeImageBackedTexture getIcon(ModContainer mod, int preferredSize) { + public static DynamicTexture getIcon(ModContainer mod, int preferredSize) { ModMetadata meta = mod.getMetadata(); String modId = meta.getId(); String iconPath = meta.getIconPath(preferredSize).orElse("assets/" + modId + "/icon.png"); @@ -66,7 +66,7 @@ public static NativeImageBackedTexture getIcon(ModContainer mod, int preferredSi ModContainer iconSource = FabricLoader.getInstance() .getModContainer(modId) .orElseThrow(() -> new RuntimeException("Cannot get ModContainer for Fabric mod with id " + finalIconSourceId)); - NativeImageBackedTexture icon = createIcon(iconSource, iconPath); + DynamicTexture icon = createIcon(iconSource, iconPath); return icon; } } diff --git a/src/main/java/dev/hephaestus/glowcase/client/util/NoteTextColorResource.java b/src/main/java/dev/hephaestus/glowcase/client/util/NoteTextColorResource.java index 64232a7c..1a137d73 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/util/NoteTextColorResource.java +++ b/src/main/java/dev/hephaestus/glowcase/client/util/NoteTextColorResource.java @@ -2,29 +2,28 @@ import dev.hephaestus.glowcase.Glowcase; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.SynchronousResourceReloader; -import net.minecraft.util.Identifier; - +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.ResourceManagerReloadListener; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.util.Optional; -public class NoteTextColorResource implements SynchronousResourceReloader, IdentifiableResourceReloadListener { +public class NoteTextColorResource implements ResourceManagerReloadListener, IdentifiableResourceReloadListener { private static final Identifier TEXTURE = Glowcase.id("textures/gui/note.png"); public static int TXT_COLOR = 0x000000; @Override - public void reload(ResourceManager manager) { + public void onResourceManagerReload(ResourceManager manager) { Optional resource = manager.getResource(TEXTURE); if (resource.isPresent()) { try { - InputStream inputStream = resource.get().getInputStream(); + InputStream inputStream = resource.get().open(); BufferedImage image = ImageIO.read(inputStream); TXT_COLOR = image.getRGB(image.getWidth()-1, image.getHeight()-1); diff --git a/src/main/java/dev/hephaestus/glowcase/client/util/SoundPlayerProxy.java b/src/main/java/dev/hephaestus/glowcase/client/util/SoundPlayerProxy.java index c3dec3d1..e56571ef 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/util/SoundPlayerProxy.java +++ b/src/main/java/dev/hephaestus/glowcase/client/util/SoundPlayerProxy.java @@ -1,13 +1,14 @@ package dev.hephaestus.glowcase.client.util; -import net.minecraft.client.sound.SoundInstance; +import dev.hephaestus.glowcase.mixin.client.sound.SoundEngineMixin; +import net.minecraft.client.resources.sounds.SoundInstance; /** * A peek into the sound system to query whether sounds are queued. * * @author Ampflower * @see dev.hephaestus.glowcase.mixin.client.sound.SoundManagerMixin - * @see dev.hephaestus.glowcase.mixin.client.sound.SoundSystemMixin + * @see SoundEngineMixin **/ public interface SoundPlayerProxy { /** @@ -16,7 +17,7 @@ public interface SoundPlayerProxy { * @param sound The sound instance to check for. * @return Whether the given sound instance is queued, but not playing. * @see #glowcase$isQueuedOrPlaying(SoundInstance) - * @see net.minecraft.client.sound.SoundManager#isPlaying(SoundInstance) + * @see net.minecraft.client.sounds.SoundManager#isActive(SoundInstance) */ boolean glowcase$isQueued(SoundInstance sound); @@ -26,7 +27,7 @@ public interface SoundPlayerProxy { * @param sound The sound instance to check for. * @return Whether the given sound instance is queued or currently playing. * @see #glowcase$isQueued(SoundInstance) - * @see net.minecraft.client.sound.SoundManager#isPlaying(SoundInstance) + * @see net.minecraft.client.sounds.SoundManager#isActive(SoundInstance) */ boolean glowcase$isQueuedOrPlaying(SoundInstance sound); } diff --git a/src/main/java/dev/hephaestus/glowcase/compat/PolydexCompatibility.java b/src/main/java/dev/hephaestus/glowcase/compat/PolydexCompatibility.java index e696871f..e1339f1f 100644 --- a/src/main/java/dev/hephaestus/glowcase/compat/PolydexCompatibility.java +++ b/src/main/java/dev/hephaestus/glowcase/compat/PolydexCompatibility.java @@ -1,62 +1,61 @@ package dev.hephaestus.glowcase.compat; -import dev.hephaestus.glowcase.Glowcase; -import dev.hephaestus.glowcase.block.entity.ConfigLinkBlockEntity; -import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; -import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity; -import eu.pb4.polydex.api.v1.hover.HoverDisplayBuilder; -import eu.pb4.polydex.impl.PolydexImpl; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.Registries; -import net.minecraft.text.Text; - -/** - * Makes Polydex hover display more correct information - * - * @author Patbox - */ -public class PolydexCompatibility { - public static void onInitialize() { - HoverDisplayBuilder.register(Glowcase.ITEM_DISPLAY_BLOCK.get(), PolydexCompatibility::setupItemDisplayBlock); - HoverDisplayBuilder.register(Glowcase.HYPERLINK_BLOCK.get(), PolydexCompatibility::setupHyperlinkBlock); - HoverDisplayBuilder.register(Glowcase.CONFIG_LINK_BLOCK.get(), PolydexCompatibility::setupConfigLinkBlock); - } - - private static void setupHyperlinkBlock(HoverDisplayBuilder hoverDisplayBuilder) { - var target = hoverDisplayBuilder.getTarget(); - if (target.player().isCreative()) { - return; - } - - if (target.blockEntity() instanceof HyperlinkBlockEntity blockEntity && !blockEntity.getUrl().isEmpty()) { - hoverDisplayBuilder.setComponent(HoverDisplayBuilder.NAME, Text.literal(blockEntity.getUrl())); - hoverDisplayBuilder.setComponent(HoverDisplayBuilder.MOD_SOURCE, Text.literal("Internet")); - } - } - - private static void setupConfigLinkBlock(HoverDisplayBuilder hoverDisplayBuilder) { - var target = hoverDisplayBuilder.getTarget(); - if (target.player().isCreative()) { - return; - } - - if (target.blockEntity() instanceof ConfigLinkBlockEntity blockEntity && !blockEntity.getUrl().isEmpty()) { - hoverDisplayBuilder.setComponent(HoverDisplayBuilder.NAME, Text.literal(blockEntity.getUrl())); - hoverDisplayBuilder.setComponent(HoverDisplayBuilder.MOD_SOURCE, Text.literal("Mod Config")); - } - } - - private static void setupItemDisplayBlock(HoverDisplayBuilder hoverDisplayBuilder) { - var target = hoverDisplayBuilder.getTarget(); - if (target.player().isCreative()) { - return; - } - - if (target.blockEntity() instanceof ItemDisplayBlockEntity blockEntity && !blockEntity.matchesStack(ItemStack.EMPTY)) { - var item = blockEntity.getStack(); - hoverDisplayBuilder.setComponent(HoverDisplayBuilder.NAME, item.getName()); - // I won't break this I promise - hoverDisplayBuilder.setComponent(HoverDisplayBuilder.MOD_SOURCE, PolydexImpl.getMod(Registries.ITEM.getId(item.getItem()))); - } - } -} +//import dev.hephaestus.glowcase.Glowcase; +//import dev.hephaestus.glowcase.block.entity.ConfigLinkBlockEntity; +//import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; +//import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity; +//import eu.pb4.polydex.api.v1.hover.HoverDisplayBuilder; +//import eu.pb4.polydex.impl.PolydexImpl; +//import net.minecraft.core.registries.BuiltInRegistries; +//import net.minecraft.network.chat.Component; +//import net.minecraft.world.item.ItemStack; +// +// * Makes Polydex hover display more correct information +// * +// * @author Patbox +// */ +//public class PolydexCompatibility { +// public static void onInitialize() { +// HoverDisplayBuilder.register(Glowcase.ITEM_DISPLAY_BLOCK.get(), PolydexCompatibility::setupItemDisplayBlock); +// HoverDisplayBuilder.register(Glowcase.HYPERLINK_BLOCK.get(), PolydexCompatibility::setupHyperlinkBlock); +// HoverDisplayBuilder.register(Glowcase.CONFIG_LINK_BLOCK.get(), PolydexCompatibility::setupConfigLinkBlock); +// } +// +// private static void setupHyperlinkBlock(HoverDisplayBuilder hoverDisplayBuilder) { +// var target = hoverDisplayBuilder.getTarget(); +// if (target.player().isCreative()) { +// return; +// } +// +// if (target.blockEntity() instanceof HyperlinkBlockEntity blockEntity && !blockEntity.getUrl().isEmpty()) { +// hoverDisplayBuilder.setComponent(HoverDisplayBuilder.NAME, Component.literal(blockEntity.getUrl())); +// hoverDisplayBuilder.setComponent(HoverDisplayBuilder.MOD_SOURCE, Component.literal("Internet")); +// } +// } +// +// private static void setupConfigLinkBlock(HoverDisplayBuilder hoverDisplayBuilder) { +// var target = hoverDisplayBuilder.getTarget(); +// if (target.player().isCreative()) { +// return; +// } +// +// if (target.blockEntity() instanceof ConfigLinkBlockEntity blockEntity && !blockEntity.getUrl().isEmpty()) { +// hoverDisplayBuilder.setComponent(HoverDisplayBuilder.NAME, Component.literal(blockEntity.getUrl())); +// hoverDisplayBuilder.setComponent(HoverDisplayBuilder.MOD_SOURCE, Component.literal("Mod Config")); +// } +// } +// +// private static void setupItemDisplayBlock(HoverDisplayBuilder hoverDisplayBuilder) { +// var target = hoverDisplayBuilder.getTarget(); +// if (target.player().isCreative()) { +// return; +// } +// +// if (target.blockEntity() instanceof ItemDisplayBlockEntity blockEntity && !blockEntity.matchesStack(ItemStack.EMPTY)) { +// var item = blockEntity.getStack(); +// hoverDisplayBuilder.setComponent(HoverDisplayBuilder.NAME, item.getHoverName()); +// // I won't break this I promise +// hoverDisplayBuilder.setComponent(HoverDisplayBuilder.MOD_SOURCE, PolydexImpl.getMod(BuiltInRegistries.ITEM.getKey(item.getItem()))); +// } +// } +//} diff --git a/src/main/java/dev/hephaestus/glowcase/datagen/client/GlowcaseModelGenerator.java b/src/main/java/dev/hephaestus/glowcase/datagen/client/GlowcaseModelGenerator.java index 72a310e0..23d61050 100644 --- a/src/main/java/dev/hephaestus/glowcase/datagen/client/GlowcaseModelGenerator.java +++ b/src/main/java/dev/hephaestus/glowcase/datagen/client/GlowcaseModelGenerator.java @@ -4,44 +4,51 @@ import dev.hephaestus.glowcase.block.ItemAcceptorBlock; import dev.hephaestus.glowcase.client.render.item.tint.GlowcaseTintSource; import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider; -import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; -import net.minecraft.client.data.*; -import net.minecraft.client.render.model.json.WeightedVariant; -import net.minecraft.item.Item; -import net.minecraft.state.property.Properties; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.Direction; +import net.fabricmc.fabric.api.datagen.v1.FabricPackOutput; +import net.minecraft.client.data.models.BlockModelGenerators; +import net.minecraft.client.data.models.ItemModelGenerators; +import net.minecraft.client.data.models.MultiVariant; +import net.minecraft.client.data.models.blockstates.MultiVariantGenerator; +import net.minecraft.client.data.models.blockstates.PropertyDispatch; +import net.minecraft.client.data.models.model.ItemModelUtils; +import net.minecraft.client.data.models.model.ModelLocationUtils; +import net.minecraft.client.data.models.model.ModelTemplates; +import net.minecraft.client.data.models.model.TextureMapping; +import net.minecraft.client.data.models.model.TexturedModel; +import net.minecraft.core.Direction; +import net.minecraft.resources.Identifier; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class GlowcaseModelGenerator extends FabricModelProvider { - public static final TexturedModel.Factory PARTICLE_FACTORY = TexturedModel.makeFactory(block -> TextureMap.all(Blocks.BEDROCK), Models.PARTICLE); + public static final TexturedModel.Provider PARTICLE_FACTORY = TexturedModel.createDefault(block -> TextureMapping.cube(Blocks.BEDROCK), ModelTemplates.PARTICLE_ONLY); - public GlowcaseModelGenerator(FabricDataOutput output) { + public GlowcaseModelGenerator(FabricPackOutput output) { super(output); } @Override - public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { - blockStateModelGenerator.registerSingleton(Glowcase.HYPERLINK_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.CONFIG_LINK_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.ITEM_DISPLAY_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.ITEM_PROVIDER_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.PARTICLE_DISPLAY.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.SOUND_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.TEXT_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.POPUP_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.SCREEN_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.SPRITE_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.RECIPE_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.OUTLINE_BLOCK.get(), PARTICLE_FACTORY); - blockStateModelGenerator.registerSingleton(Glowcase.ENTITY_DISPLAY_BLOCK.get(), PARTICLE_FACTORY); + public void generateBlockStateModels(BlockModelGenerators blockStateModelGenerator) { + blockStateModelGenerator.createTrivialBlock(Glowcase.HYPERLINK_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.CONFIG_LINK_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.ITEM_DISPLAY_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.ITEM_PROVIDER_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.PARTICLE_DISPLAY.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.SOUND_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.TEXT_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.POPUP_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.SCREEN_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.SPRITE_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.RECIPE_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.OUTLINE_BLOCK.get(), PARTICLE_FACTORY); + blockStateModelGenerator.createTrivialBlock(Glowcase.ENTITY_DISPLAY_BLOCK.get(), PARTICLE_FACTORY); registerItemAcceptor(blockStateModelGenerator); } @Override - public void generateItemModels(ItemModelGenerator itemModelGenerator) { + public void generateItemModels(ItemModelGenerators itemModelGenerator) { // Block items registerGlowcaseDyeable(itemModelGenerator, Glowcase.HYPERLINK_BLOCK_ITEM.get(), 0xFFFFFFFF); registerGlowcaseDyeable(itemModelGenerator, Glowcase.CONFIG_LINK_BLOCK_ITEM.get(), 0xFFFFFFFF); @@ -53,37 +60,37 @@ public void generateItemModels(ItemModelGenerator itemModelGenerator) { registerGlowcaseDyeable(itemModelGenerator, Glowcase.POPUP_BLOCK_ITEM.get(), 0xFFFFFFFF); registerGlowcaseDyeable(itemModelGenerator, Glowcase.SCREEN_BLOCK_ITEM.get(), 0xFFFFFFFF); registerGlowcaseDyeable(itemModelGenerator, Glowcase.SPRITE_BLOCK_ITEM.get(), 0xFFFFFFFF); - itemModelGenerator.register(Glowcase.RECIPE_BLOCK_ITEM.get(), Models.GENERATED); + itemModelGenerator.generateFlatItem(Glowcase.RECIPE_BLOCK_ITEM.get(), ModelTemplates.FLAT_ITEM); registerGlowcaseDyeable(itemModelGenerator, Glowcase.OUTLINE_BLOCK_ITEM.get(), 0xFFFFFFFF); registerGlowcaseDyeable(itemModelGenerator, Glowcase.ENTITY_DISPLAY_BLOCK_ITEM.get(), 0xFFFFFFFF); // Simple items - itemModelGenerator.register(Glowcase.LOCK_ITEM.get(), Models.GENERATED); - itemModelGenerator.registerDyeable(Glowcase.COLLECTION_CASE_ITEM.get(), 0xFFFFFFFF); - itemModelGenerator.register(Glowcase.TABLET_ITEM.get(), Models.GENERATED); - itemModelGenerator.register(Glowcase.NOTE_ITEM.get(), Models.GENERATED); + itemModelGenerator.generateFlatItem(Glowcase.LOCK_ITEM.get(), ModelTemplates.FLAT_ITEM); + itemModelGenerator.generateDyedItem(Glowcase.COLLECTION_CASE_ITEM.get(), 0xFFFFFFFF); + itemModelGenerator.generateFlatItem(Glowcase.TABLET_ITEM.get(), ModelTemplates.FLAT_ITEM); + itemModelGenerator.generateFlatItem(Glowcase.NOTE_ITEM.get(), ModelTemplates.FLAT_ITEM); } - private void registerItemAcceptor(BlockStateModelGenerator generator) { + private void registerItemAcceptor(BlockModelGenerators generator) { ItemAcceptorBlock block = Glowcase.ITEM_ACCEPTOR_BLOCK.get(); - WeightedVariant weightedVariant = BlockStateModelGenerator.createWeightedVariant(ModelIds.getBlockModelId(block)); - WeightedVariant weightedVariant2 = BlockStateModelGenerator.createWeightedVariant(ModelIds.getBlockSubModelId(block, "_on")); - generator.blockStateCollector + MultiVariant weightedVariant = BlockModelGenerators.plainVariant(ModelLocationUtils.getModelLocation(block)); + MultiVariant weightedVariant2 = BlockModelGenerators.plainVariant(ModelLocationUtils.getModelLocation(block, "_on")); + generator.blockStateOutput .accept( - VariantsBlockModelDefinitionCreator.of(block) - .with(BlockStateModelGenerator.createBooleanModelMap(Properties.POWERED, weightedVariant2, weightedVariant)) - .coordinate( - BlockStateVariantMap.operations(Properties.HORIZONTAL_FACING) - .register(Direction.WEST, BlockStateModelGenerator.ROTATE_Y_270) - .register(Direction.SOUTH, BlockStateModelGenerator.ROTATE_Y_180) - .register(Direction.NORTH, BlockStateModelGenerator.NO_OP) - .register(Direction.EAST, BlockStateModelGenerator.ROTATE_Y_90) + MultiVariantGenerator.dispatch(block) + .with(BlockModelGenerators.createBooleanModelDispatch(BlockStateProperties.POWERED, weightedVariant2, weightedVariant)) + .with( + PropertyDispatch.modify(BlockStateProperties.HORIZONTAL_FACING) + .select(Direction.WEST, BlockModelGenerators.Y_ROT_270) + .select(Direction.SOUTH, BlockModelGenerators.Y_ROT_180) + .select(Direction.NORTH, BlockModelGenerators.NOP) + .select(Direction.EAST, BlockModelGenerators.Y_ROT_90) ) ); } - public final void registerGlowcaseDyeable(ItemModelGenerator generator, Item item, int defaultColor) { - Identifier identifier = generator.upload(item, Models.GENERATED); - generator.output.accept(item, ItemModels.tinted(identifier, new GlowcaseTintSource(defaultColor))); + public final void registerGlowcaseDyeable(ItemModelGenerators generator, Item item, int defaultColor) { + Identifier identifier = generator.createFlatItemModel(item, ModelTemplates.FLAT_ITEM); + generator.itemModelOutput.accept(item, ItemModelUtils.tintedModel(identifier, new GlowcaseTintSource(defaultColor))); } } diff --git a/src/main/java/dev/hephaestus/glowcase/item/CollectionCaseItem.java b/src/main/java/dev/hephaestus/glowcase/item/CollectionCaseItem.java index 2b2b3711..a11f0a4c 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/CollectionCaseItem.java +++ b/src/main/java/dev/hephaestus/glowcase/item/CollectionCaseItem.java @@ -3,30 +3,29 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.item.component.CollectionComponent; import dev.hephaestus.glowcase.util.CollectableStack; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.StackReference; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.screen.slot.Slot; -import net.minecraft.sound.SoundEvents; -import net.minecraft.text.Text; -import net.minecraft.util.ClickType; -import net.minecraft.util.Formatting; - import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.SlotAccess; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.ClickAction; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; public class CollectionCaseItem extends Item implements ScrollableItem { - public CollectionCaseItem(Settings settings) { + public CollectionCaseItem(Properties settings) { super(settings); } - public boolean bundleInteract(ItemStack caseStack, ItemStack otherStack, ClickType clickType, PlayerEntity player, Consumer otherStackSetter, boolean tooltipVisible) { + public boolean bundleInteract(ItemStack caseStack, ItemStack otherStack, ClickAction clickType, Player player, Consumer otherStackSetter, boolean tooltipVisible) { CollectionComponent collection = caseStack.get(Glowcase.COLLECTION_COMPONENT.get()); - if (collection != null && clickType.equals(ClickType.RIGHT)) { + if (collection != null && clickType.equals(ClickAction.SECONDARY)) { if (otherStack.isEmpty()) { // Removal Actions ItemStack retrievedStack = collection.getSelectedCollectableStack(); if (!retrievedStack.isEmpty() && collection.isSelectedCollected()) { // Retrieve Collectable @@ -42,7 +41,7 @@ public boolean bundleInteract(ItemStack caseStack, ItemStack otherStack, ClickTy } else { // Insertion Actions int collectionIndex = collection.getCollectionIndex(otherStack); if (collectionIndex != -1) { // Collect Collectable - otherStack.decrement(collection.collectables().get(collectionIndex).getStack().getCount()); + otherStack.shrink(collection.collectables().get(collectionIndex).getStack().getCount()); caseStack.set(Glowcase.COLLECTION_COMPONENT.get(), collection.collectStack(collectionIndex)); playCollectSound(player); return true; @@ -57,17 +56,17 @@ public boolean bundleInteract(ItemStack caseStack, ItemStack otherStack, ClickTy } @Override - public boolean onStackClicked(ItemStack caseStack, Slot slot, ClickType clickType, PlayerEntity player) { - return bundleInteract(caseStack, slot.getStack(), clickType, player, slot::setStack, false) || super.onStackClicked(caseStack, slot, clickType, player); + public boolean overrideStackedOnOther(ItemStack caseStack, Slot slot, ClickAction clickType, Player player) { + return bundleInteract(caseStack, slot.getItem(), clickType, player, slot::setByPlayer, false) || super.overrideStackedOnOther(caseStack, slot, clickType, player); } @Override - public boolean onClicked(ItemStack caseStack, ItemStack otherStack, Slot slot, ClickType clickType, PlayerEntity player, StackReference cursorStackReference) { - return bundleInteract(caseStack, otherStack, clickType, player, cursorStackReference::set, true) || super.onClicked(caseStack, otherStack, slot, clickType, player, cursorStackReference); + public boolean overrideOtherStackedOnMe(ItemStack caseStack, ItemStack otherStack, Slot slot, ClickAction clickType, Player player, SlotAccess cursorStackReference) { + return bundleInteract(caseStack, otherStack, clickType, player, cursorStackReference::set, true) || super.overrideOtherStackedOnMe(caseStack, otherStack, slot, clickType, player, cursorStackReference); } @Override - public void scroll(ItemStack caseStack, PlayerEntity player, int amount) { + public void scroll(ItemStack caseStack, Player player, int amount) { CollectionComponent collection = caseStack.get(Glowcase.COLLECTION_COMPONENT.get()); if (collection != null) { if (amount > 0) { @@ -86,38 +85,38 @@ public void scroll(ItemStack caseStack, PlayerEntity player, int amount) { } @Override - public void appendTooltip(ItemStack stack, TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - super.appendTooltip(stack, context, displayComponent, textConsumer, type); + public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + super.appendHoverText(stack, context, displayComponent, textConsumer, type); CollectionComponent collection = stack.get(Glowcase.COLLECTION_COMPONENT.get()); - textConsumer.accept(Text.translatable("item.glowcase.collection_case.tooltip.0").formatted(Formatting.GRAY)); - if (type.isCreative()) textConsumer.accept(Text.translatable("item.glowcase.collection_case.tooltip.creative.0").formatted(Formatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("item.glowcase.collection_case.tooltip.0").withStyle(ChatFormatting.GRAY)); + if (type.isCreative()) textConsumer.accept(Component.translatable("item.glowcase.collection_case.tooltip.creative.0").withStyle(ChatFormatting.DARK_GRAY)); if (collection != null && !collection.collectables().isEmpty()) { - textConsumer.accept(Text.translatable("item.glowcase.collection_case.tooltip.1", collection.collected(), collection.collectables().size()).formatted(Formatting.DARK_PURPLE)); + textConsumer.accept(Component.translatable("item.glowcase.collection_case.tooltip.1", collection.collected(), collection.collectables().size()).withStyle(ChatFormatting.DARK_PURPLE)); for (int i = 0; i < collection.collectables().size(); i++) { CollectableStack collectable = collection.collectables().get(i); - textConsumer.accept(collectable.getCollectableName(context.getRegistryLookup(), collection.selected() == i)); + textConsumer.accept(collectable.getCollectableName(context.registries(), collection.selected() == i)); } } } private void playScrollSound(Entity entity) { - entity.playSound(SoundEvents.BLOCK_LEVER_CLICK, 0.2F, 1.2F); + entity.playSound(SoundEvents.LEVER_CLICK, 0.2F, 1.2F); } private void playRetrieveSound(Entity entity) { - entity.playSound(SoundEvents.ITEM_BUNDLE_REMOVE_ONE, 0.8F, 0.8F + entity.getWorld().getRandom().nextFloat() * 0.4F); + entity.playSound(SoundEvents.BUNDLE_REMOVE_ONE, 0.8F, 0.8F + entity.level().getRandom().nextFloat() * 0.4F); } private void playRemoveSound(Entity entity) { - entity.playSound(SoundEvents.BLOCK_CHISELED_BOOKSHELF_INSERT, 0.8F, 0.8F + entity.getWorld().getRandom().nextFloat() * 0.4F); + entity.playSound(SoundEvents.CHISELED_BOOKSHELF_INSERT, 0.8F, 0.8F + entity.level().getRandom().nextFloat() * 0.4F); } private void playAddSound(Entity entity) { - entity.playSound(SoundEvents.BLOCK_CHISELED_BOOKSHELF_PICKUP, 0.8F, 0.8F + entity.getWorld().getRandom().nextFloat() * 0.4F); + entity.playSound(SoundEvents.CHISELED_BOOKSHELF_PICKUP, 0.8F, 0.8F + entity.level().getRandom().nextFloat() * 0.4F); } private void playCollectSound(Entity entity) { - entity.playSound(SoundEvents.ITEM_BUNDLE_INSERT, 0.8F, 0.8F + entity.getWorld().getRandom().nextFloat() * 0.4F); + entity.playSound(SoundEvents.BUNDLE_INSERT, 0.8F, 0.8F + entity.level().getRandom().nextFloat() * 0.4F); } } diff --git a/src/main/java/dev/hephaestus/glowcase/item/LockItem.java b/src/main/java/dev/hephaestus/glowcase/item/LockItem.java index 2dbf50dd..bbc4ac7e 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/LockItem.java +++ b/src/main/java/dev/hephaestus/glowcase/item/LockItem.java @@ -1,73 +1,72 @@ package dev.hephaestus.glowcase.item; -import dev.hephaestus.glowcase.mixin.LockableContainerBlockEntityAccessor; -import net.minecraft.block.entity.LockableContainerBlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.ContainerLock; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsageContext; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.predicate.NumberRange; -import net.minecraft.predicate.item.ItemPredicate; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvent; -import net.minecraft.sound.SoundEvents; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.world.World; +import dev.hephaestus.glowcase.mixin.BaseContainerBlockEntityAccessor; -import java.util.List; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.advancements.criterion.ItemPredicate; +import net.minecraft.advancements.criterion.MinMaxBounds; +import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.LockCode; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; public class LockItem extends Item { /** * Use an impossible condition for the lock */ - public static final ContainerLock CONTAINER_LOCK = new ContainerLock(ItemPredicate.Builder.create().count(NumberRange.IntRange.exactly(Integer.MIN_VALUE)).build()); + public static final LockCode CONTAINER_LOCK = new LockCode(ItemPredicate.Builder.item().withCount(MinMaxBounds.Ints.exactly(Integer.MIN_VALUE)).build()); - public LockItem(Settings settings) { + public LockItem(Properties settings) { super(settings); } @Override - public ActionResult useOnBlock(ItemUsageContext context) { - World world = context.getWorld(); - PlayerEntity player = context.getPlayer(); - if (world.isClient || + public InteractionResult useOn(UseOnContext context) { + Level world = context.getLevel(); + Player player = context.getPlayer(); + if (world.isClientSide() || player == null || !player.isCreative() || - !(world.getBlockEntity(context.getBlockPos()) instanceof LockableContainerBlockEntity be)) { - return ActionResult.PASS; + !(world.getBlockEntity(context.getClickedPos()) instanceof BaseContainerBlockEntity be)) { + return InteractionResult.PASS; } - var bea = (LockableContainerBlockEntityAccessor) be; - Text message; + var bea = (BaseContainerBlockEntityAccessor) be; + Component message; SoundEvent soundEvent; - if (bea.glowcase$getLock().equals(ContainerLock.EMPTY)) { + if (bea.glowcase$getLock().equals(LockCode.NO_LOCK)) { bea.glowcase$setLock(CONTAINER_LOCK); - message = Text.translatable("gui.glowcase.locked_block", be.getDisplayName()); - soundEvent = SoundEvents.BLOCK_WOODEN_TRAPDOOR_CLOSE; + message = Component.translatable("gui.glowcase.locked_block", be.getDisplayName()); + soundEvent = SoundEvents.WOODEN_TRAPDOOR_CLOSE; } else { - bea.glowcase$setLock(ContainerLock.EMPTY); - message = Text.translatable("gui.glowcase.unlocked_block", be.getDisplayName()); - soundEvent = SoundEvents.BLOCK_WOODEN_TRAPDOOR_OPEN; + bea.glowcase$setLock(LockCode.NO_LOCK); + message = Component.translatable("gui.glowcase.unlocked_block", be.getDisplayName()); + soundEvent = SoundEvents.WOODEN_TRAPDOOR_OPEN; } - player.sendMessage(message, true); - player.playSoundToPlayer(soundEvent, SoundCategory.BLOCKS, 1.0F, 1.0F); - be.markDirty(); + player.sendOverlayMessage(message); + player.playSound(soundEvent,1.0F, 1.0F); + be.setChanged(); - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } @Override - public void appendTooltip(ItemStack stack, TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - super.appendTooltip(stack, context, displayComponent, textConsumer, type); + public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + super.appendHoverText(stack, context, displayComponent, textConsumer, type); - textConsumer.accept(Text.translatable("item.glowcase.lock.tooltip.0").formatted(Formatting.GRAY)); + textConsumer.accept(Component.translatable("item.glowcase.lock.tooltip.0").withStyle(ChatFormatting.GRAY)); } } diff --git a/src/main/java/dev/hephaestus/glowcase/item/NoteItem.java b/src/main/java/dev/hephaestus/glowcase/item/NoteItem.java index b9b4a206..f891bfc5 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/NoteItem.java +++ b/src/main/java/dev/hephaestus/glowcase/item/NoteItem.java @@ -2,71 +2,70 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.item.component.NoteComponent; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Formatting; -import net.minecraft.util.Hand; -import net.minecraft.world.World; - import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.Level; public class NoteItem extends Item { - public NoteItem(Settings settings) { + public NoteItem(Properties settings) { super(settings); } @Override - public ActionResult use(World world, PlayerEntity user, Hand hand) { - ItemStack stackInHand = user.getStackInHand(hand); + public InteractionResult use(Level world, Player user, InteractionHand hand) { + ItemStack stackInHand = user.getItemInHand(hand); NoteComponent noteComponent = stackInHand.get(Glowcase.NOTE_COMPONENT.get()); // Only edit when not signed if (noteComponent != null && noteComponent.title().isPresent()) - return ActionResult.PASS; + return InteractionResult.PASS; - if (world.isClient()) + if (world.isClientSide()) Glowcase.proxy.openNoteEditScreen(stackInHand); - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } @Override - public Text getName(ItemStack stack) { - if (stack.contains(Glowcase.NOTE_COMPONENT.get())) { + public Component getName(ItemStack stack) { + if (stack.has(Glowcase.NOTE_COMPONENT.get())) { NoteComponent noteComponent = stack.get(Glowcase.NOTE_COMPONENT.get()); assert noteComponent != null; if (noteComponent.title().isPresent()) - return Text.literal(noteComponent.title().get()).setStyle(Style.EMPTY.withItalic(true)); + return Component.literal(noteComponent.title().get()).setStyle(Style.EMPTY.withItalic(true)); } return super.getName(stack); } @Override - public void appendTooltip(ItemStack itemStack, TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { + public void appendHoverText(ItemStack itemStack, TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { boolean signed = false; - if (itemStack.contains(Glowcase.NOTE_COMPONENT.get())) { + if (itemStack.has(Glowcase.NOTE_COMPONENT.get())) { NoteComponent noteComponent = itemStack.get(Glowcase.NOTE_COMPONENT.get()); assert noteComponent != null; if (noteComponent.title().isPresent()) { signed = true; - Text author = (noteComponent.author().isPresent()) ? Text.literal(noteComponent.author().get()) : Text.translatable("gui.glowcase.note.anonymous").formatted(Formatting.WHITE); + Component author = (noteComponent.author().isPresent()) ? Component.literal(noteComponent.author().get()) : Component.translatable("gui.glowcase.note.anonymous").withStyle(ChatFormatting.WHITE); - textConsumer.accept(Text.translatable("item.glowcase.note.tooltip.0", author).formatted(Formatting.YELLOW)); + textConsumer.accept(Component.translatable("item.glowcase.note.tooltip.0", author).withStyle(ChatFormatting.YELLOW)); } } if (!signed) { - textConsumer.accept(Text.translatable("item.glowcase.note.tooltip.1").formatted(Formatting.GRAY)); + textConsumer.accept(Component.translatable("item.glowcase.note.tooltip.1").withStyle(ChatFormatting.GRAY)); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/item/ScrollableItem.java b/src/main/java/dev/hephaestus/glowcase/item/ScrollableItem.java index dc214cf0..ae3ae7da 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/ScrollableItem.java +++ b/src/main/java/dev/hephaestus/glowcase/item/ScrollableItem.java @@ -1,8 +1,8 @@ package dev.hephaestus.glowcase.item; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; public interface ScrollableItem { - void scroll(ItemStack caseStack, PlayerEntity player, int amount); + void scroll(ItemStack caseStack, Player player, int amount); } diff --git a/src/main/java/dev/hephaestus/glowcase/item/TabletItem.java b/src/main/java/dev/hephaestus/glowcase/item/TabletItem.java index e65dc40e..1dd8fe85 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/TabletItem.java +++ b/src/main/java/dev/hephaestus/glowcase/item/TabletItem.java @@ -3,20 +3,22 @@ import com.mojang.datafixers.util.Pair; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ScreenBlockEntity; -import net.minecraft.component.type.TooltipDisplayComponent; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.StackReference; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsageContext; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.screen.slot.Slot; -import net.minecraft.text.Text; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; import net.minecraft.util.*; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.World; - +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.SlotAccess; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.ClickAction; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; import java.util.List; import java.util.UUID; import java.util.function.Consumer; @@ -24,16 +26,16 @@ import static dev.hephaestus.glowcase.block.GlowcaseBlock.canEditGlowcase; public class TabletItem extends Item { - public TabletItem(Settings settings) { + public TabletItem(Properties settings) { super(settings); } @Override - public ActionResult use(World world, PlayerEntity user, Hand hand) { - ItemStack stack = user.getStackInHand(hand); + public InteractionResult use(Level world, Player user, InteractionHand hand) { + ItemStack stack = user.getItemInHand(hand); - if (world.isClient() || !stack.contains(Glowcase.SLIDESHOW_COMPONENT.get()) || !stack.contains(Glowcase.LINKED_SCREEN_COMPONENT.get())) - return ActionResult.PASS; + if (world.isClientSide() || !stack.has(Glowcase.SLIDESHOW_COMPONENT.get()) || !stack.has(Glowcase.LINKED_SCREEN_COMPONENT.get())) + return InteractionResult.PASS; // Get components @@ -44,7 +46,7 @@ public ActionResult use(World world, PlayerEntity user, Hand hand) { assert screenPos != null; int index = stack.getOrDefault(Glowcase.CURRENT_SLIDE_COMPONENT.get(), 0); - int step = user.isSneaking() ? -1 : 1; + int step = user.isShiftKeyDown() ? -1 : 1; index += step; // Ensure boundaries @@ -58,7 +60,7 @@ public ActionResult use(World world, PlayerEntity user, Hand hand) { if (!(world.getBlockEntity(screenPos.getSecond()) instanceof ScreenBlockEntity screen && screen.macaddress.equals(screenPos.getFirst()))) { // Link is invalid stack.remove(Glowcase.LINKED_SCREEN_COMPONENT.get()); - return ActionResult.PASS; + return InteractionResult.PASS; } Pair slide = slideshow.get(index); @@ -70,25 +72,25 @@ public ActionResult use(World world, PlayerEntity user, Hand hand) { } else screen.setImage(slide.getFirst(), slide.getSecond(), null); - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } @Override - public ActionResult useOnBlock(ItemUsageContext context) { - PlayerEntity player = context.getPlayer(); - BlockPos pos = context.getBlockPos(); - ItemStack stack = context.getStack(); - World world = context.getWorld(); + public InteractionResult useOn(UseOnContext context) { + Player player = context.getPlayer(); + BlockPos pos = context.getClickedPos(); + ItemStack stack = context.getItemInHand(); + Level world = context.getLevel(); - if (world.isClient() || player == null) - return ActionResult.PASS; + if (world.isClientSide() || player == null) + return InteractionResult.PASS; - if (!(player.isSneaking() && world.getBlockEntity(pos) instanceof ScreenBlockEntity screen)) - return ActionResult.PASS; + if (!(player.isShiftKeyDown() && world.getBlockEntity(pos) instanceof ScreenBlockEntity screen)) + return InteractionResult.PASS; if (!canEditGlowcase(player, pos)) { - player.sendMessage(Text.translatable("gui.glowcase.linking_denied"), true); - return ActionResult.SUCCESS; + player.sendOverlayMessage(Component.translatable("gui.glowcase.linking_denied")); + return InteractionResult.SUCCESS; } // Update linked block @@ -96,40 +98,40 @@ public ActionResult useOnBlock(ItemUsageContext context) { Pair linkedScreen = stack.getOrDefault(Glowcase.LINKED_SCREEN_COMPONENT.get(), null); if (linkedScreen != null && screen.macaddress.equals(linkedScreen.getFirst()) && linkedScreen.getSecond().equals(pos)) { stack.remove(Glowcase.LINKED_SCREEN_COMPONENT.get()); - player.sendMessage(Text.translatable("gui.glowcase.unlinked_screen"), true); + player.sendOverlayMessage(Component.translatable("gui.glowcase.unlinked_screen")); } else { stack.set(Glowcase.LINKED_SCREEN_COMPONENT.get(), new Pair<>(screen.macaddress, pos)); - player.sendMessage(Text.translatable("gui.glowcase.updated_linked_screen", pos.toShortString()), true); + player.sendOverlayMessage(Component.translatable("gui.glowcase.updated_linked_screen", pos.toShortString())); } - return ActionResult.SUCCESS; + return InteractionResult.SUCCESS; } @Override - public boolean onClicked(ItemStack stack, ItemStack otherStack, Slot slot, ClickType clickType, PlayerEntity player, StackReference cursorStackReference) { - if (clickType == ClickType.RIGHT && otherStack.isEmpty()) { + public boolean overrideOtherStackedOnMe(ItemStack stack, ItemStack otherStack, Slot slot, ClickAction clickType, Player player, SlotAccess cursorStackReference) { + if (clickType == ClickAction.SECONDARY && otherStack.isEmpty()) { // Open Editor on Client - if (stack.contains(Glowcase.LINKED_SCREEN_COMPONENT.get())) { + if (stack.has(Glowcase.LINKED_SCREEN_COMPONENT.get())) { // Ensure linked screen is correct before we send the client a wrong connection Pair linkedScreen = stack.get(Glowcase.LINKED_SCREEN_COMPONENT.get()); assert linkedScreen != null; - if (!(player.getWorld().getBlockEntity(linkedScreen.getSecond()) instanceof ScreenBlockEntity screen && screen.macaddress.equals(linkedScreen.getFirst()))) { + if (!(player.level().getBlockEntity(linkedScreen.getSecond()) instanceof ScreenBlockEntity screen && screen.macaddress.equals(linkedScreen.getFirst()))) { stack.remove(Glowcase.LINKED_SCREEN_COMPONENT.get()); } } - if (player.getWorld().isClient()) + if (player.level().isClientSide()) Glowcase.proxy.openTabletEditScreen(stack); return true; } - return super.onClicked(stack, otherStack, slot, clickType, player, cursorStackReference); + return super.overrideOtherStackedOnMe(stack, otherStack, slot, clickType, player, cursorStackReference); } @Override - public boolean isItemBarVisible(ItemStack stack) { - if (stack.contains(Glowcase.LINKED_SCREEN_COMPONENT.get()) && stack.contains(Glowcase.SLIDESHOW_COMPONENT.get()) && stack.contains(Glowcase.CURRENT_SLIDE_COMPONENT.get())) { + public boolean isBarVisible(ItemStack stack) { + if (stack.has(Glowcase.LINKED_SCREEN_COMPONENT.get()) && stack.has(Glowcase.SLIDESHOW_COMPONENT.get()) && stack.has(Glowcase.CURRENT_SLIDE_COMPONENT.get())) { List> slideshow = stack.get(Glowcase.SLIDESHOW_COMPONENT.get()); Integer index = stack.getOrDefault(Glowcase.CURRENT_SLIDE_COMPONENT.get(), 0); @@ -137,28 +139,28 @@ public boolean isItemBarVisible(ItemStack stack) { return true; } - return super.isItemBarVisible(stack); + return super.isBarVisible(stack); } @Override - public int getItemBarStep(ItemStack stack) { + public int getBarWidth(ItemStack stack) { List> slideshow = stack.get(Glowcase.SLIDESHOW_COMPONENT.get()); int max = (slideshow != null && !slideshow.isEmpty()) ? slideshow.size()-1 : 0; Integer index = stack.getOrDefault(Glowcase.CURRENT_SLIDE_COMPONENT.get(), 0); - return MathHelper.clamp(Math.round((float)index * 13.0F / (float)max), 0, 13); + return Mth.clamp(Math.round((float)index * 13.0F / (float)max), 0, 13); } @Override - public int getItemBarColor(ItemStack stack) { + public int getBarColor(ItemStack stack) { return 0xFFFFFF; } @Override - public void appendTooltip(ItemStack stack, TooltipContext context, TooltipDisplayComponent displayComponent, Consumer textConsumer, TooltipType type) { - textConsumer.accept(Text.translatable("item.glowcase.tablet.tooltip.0").formatted(Formatting.GRAY)); - textConsumer.accept(Text.translatable("item.glowcase.tablet.tooltip.1").formatted(Formatting.DARK_GRAY)); - textConsumer.accept(Text.translatable("item.glowcase.tablet.tooltip.2").formatted(Formatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { + textConsumer.accept(Component.translatable("item.glowcase.tablet.tooltip.0").withStyle(ChatFormatting.GRAY)); + textConsumer.accept(Component.translatable("item.glowcase.tablet.tooltip.1").withStyle(ChatFormatting.DARK_GRAY)); + textConsumer.accept(Component.translatable("item.glowcase.tablet.tooltip.2").withStyle(ChatFormatting.DARK_GRAY)); } } diff --git a/src/main/java/dev/hephaestus/glowcase/item/component/CollectionComponent.java b/src/main/java/dev/hephaestus/glowcase/item/component/CollectionComponent.java index ea361bfb..a4f4f2e8 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/component/CollectionComponent.java +++ b/src/main/java/dev/hephaestus/glowcase/item/component/CollectionComponent.java @@ -5,20 +5,19 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.util.CollectableStack; -import net.minecraft.component.ComponentType; -import net.minecraft.item.ItemStack; -import net.minecraft.network.codec.PacketCodecs; - import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.world.item.ItemStack; public record CollectionComponent(ImmutableList collectables, int selected) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.list(CollectableStack.CODEC).fieldOf("collectables").forGetter(CollectionComponent::collectables), Codec.INT.fieldOf("selected").forGetter(CollectionComponent::selected) ).apply(instance, (c, s) -> new CollectionComponent(ImmutableList.copyOf(c), s))); - public static final ComponentType TYPE = ComponentType.builder().codec(CODEC).packetCodec(PacketCodecs.registryCodec(CODEC)).build(); + public static final DataComponentType TYPE = DataComponentType.builder().persistent(CODEC).networkSynchronized(ByteBufCodecs.fromCodecWithRegistries(CODEC)).build(); public CollectionComponent() { this(ImmutableList.of(), -1); @@ -53,7 +52,7 @@ public boolean isSelectedCollected() { public CollectionComponent withStackAfterSelection(ItemStack stack) { if (stack.isEmpty()) return this; hasSelection(); - CollectableStack newCollectable = new CollectableStack(stack.getRegistryEntry(), stack.copy().getComponentChanges(), stack.getCount(), false); + CollectableStack newCollectable = new CollectableStack(stack.getItem().builtInRegistryHolder(), stack.copy().getComponentsPatch(), stack.getCount(), false); return new CollectionComponent(alteredCollectables(l -> l.add(selected + 1, newCollectable)), selected + 1); } @@ -68,7 +67,7 @@ public int getCollectionIndex(ItemStack otherStack) { CollectableStack collectable = collectables.get(i); if (!collectable.collected()) { ItemStack stackToCollect = collectable.getStack(); - if (ItemStack.areItemsAndComponentsEqual(stackToCollect, otherStack) && stackToCollect.getCount() <= otherStack.getCount()) { + if (ItemStack.isSameItemSameComponents(stackToCollect, otherStack) && stackToCollect.getCount() <= otherStack.getCount()) { return i; } } @@ -120,4 +119,4 @@ public CollectionComponent selectPrevious(boolean collected) { public int collected() { return (int) collectables.stream().filter(CollectableStack::collected).count(); } -} \ No newline at end of file +} diff --git a/src/main/java/dev/hephaestus/glowcase/item/component/NoteComponent.java b/src/main/java/dev/hephaestus/glowcase/item/component/NoteComponent.java index df4d1a18..d641b44f 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/component/NoteComponent.java +++ b/src/main/java/dev/hephaestus/glowcase/item/component/NoteComponent.java @@ -2,21 +2,20 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.component.ComponentType; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.text.Text; -import net.minecraft.text.TextCodecs; - import java.util.List; import java.util.Optional; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.ByteBufCodecs; -public record NoteComponent(List lines, Alignment alignment, Optional title, Optional author) { +public record NoteComponent(List lines, Alignment alignment, Optional title, Optional author) { public static final int LINES_LIMIT = 10; public static final int TITLE_LIMIT = 32; public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( - TextCodecs.CODEC.sizeLimitedListOf(LINES_LIMIT).fieldOf("lines").forGetter(NoteComponent::lines), + ComponentSerialization.CODEC.sizeLimitedListOf(LINES_LIMIT).fieldOf("lines").forGetter(NoteComponent::lines), Codec.BYTE.fieldOf("alignment").forGetter((note) -> (byte) note.alignment.ordinal()), Codec.STRING.optionalFieldOf("title").forGetter(NoteComponent::title), Codec.STRING.optionalFieldOf("author").forGetter(NoteComponent::author) @@ -24,9 +23,9 @@ public record NoteComponent(List lines, Alignment alignment, Optional new NoteComponent(lines, Alignment.values()[alignment], title, author)) ); - public static final ComponentType TYPE = ComponentType.builder() - .codec(CODEC) - .packetCodec(PacketCodecs.registryCodec(CODEC)) + public static final DataComponentType TYPE = DataComponentType.builder() + .persistent(CODEC) + .networkSynchronized(ByteBufCodecs.fromCodecWithRegistries(CODEC)) .build(); public enum Alignment { diff --git a/src/main/java/dev/hephaestus/glowcase/item/component/TabletComponents.java b/src/main/java/dev/hephaestus/glowcase/item/component/TabletComponents.java index 54d6ff70..e48af7a6 100644 --- a/src/main/java/dev/hephaestus/glowcase/item/component/TabletComponents.java +++ b/src/main/java/dev/hephaestus/glowcase/item/component/TabletComponents.java @@ -2,48 +2,47 @@ import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; -import net.minecraft.component.ComponentType; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.util.Util; -import net.minecraft.util.Uuids; -import net.minecraft.util.dynamic.Codecs; -import net.minecraft.util.math.BlockPos; - import java.util.Arrays; import java.util.List; import java.util.UUID; +import net.minecraft.core.BlockPos; +import net.minecraft.core.UUIDUtil; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.Util; public class TabletComponents { // TODO: Rewrite to use RecordCodecBuilder rather than three components // (see NoteComponent.java for an example) - public static final ComponentType> LINKED_SCREEN_TYPE; - public static final ComponentType CURRENT_SLIDE_TYPE; - public static final ComponentType>> SLIDESHOW_COMPONENT_TYPE; + public static final DataComponentType> LINKED_SCREEN_TYPE; + public static final DataComponentType CURRENT_SLIDE_TYPE; + public static final DataComponentType>> SLIDESHOW_COMPONENT_TYPE; static { { - Codec uuidCodec = Codec.INT_STREAM.comapFlatMap(stream -> Util.decodeFixedLengthArray(stream, 4).map(Uuids::toUuid), uuid -> Arrays.stream(Uuids.toIntArray(uuid))); + Codec uuidCodec = Codec.INT_STREAM.comapFlatMap(stream -> Util.fixedSize(stream, 4).map(UUIDUtil::uuidFromIntArray), uuid -> Arrays.stream(UUIDUtil.uuidToIntArray(uuid))); Codec> codec = Codec.mapPair(uuidCodec.fieldOf("uuid"), BlockPos.CODEC.fieldOf("pos")).codec(); - LINKED_SCREEN_TYPE = ComponentType.>builder() - .codec(codec) - .packetCodec(PacketCodecs.registryCodec(codec)) + LINKED_SCREEN_TYPE = DataComponentType.>builder() + .persistent(codec) + .networkSynchronized(ByteBufCodecs.fromCodecWithRegistries(codec)) .build(); } { - CURRENT_SLIDE_TYPE = ComponentType.builder() - .codec(Codecs.NON_NEGATIVE_INT) - .packetCodec(PacketCodecs.registryCodec(Codecs.NON_NEGATIVE_INT)) + CURRENT_SLIDE_TYPE = DataComponentType.builder() + .persistent(ExtraCodecs.NON_NEGATIVE_INT) + .networkSynchronized(ByteBufCodecs.fromCodecWithRegistries(ExtraCodecs.NON_NEGATIVE_INT)) .build(); } { Codec>> codec = Codec.mapPair(Codec.STRING.fieldOf("url"), Codec.STRING.fieldOf("alt")).codec().listOf(); - SLIDESHOW_COMPONENT_TYPE = ComponentType.>>builder() - .codec(codec) - .packetCodec(PacketCodecs.registryCodec(codec)) + SLIDESHOW_COMPONENT_TYPE = DataComponentType.>>builder() + .persistent(codec) + .networkSynchronized(ByteBufCodecs.fromCodecWithRegistries(codec)) .build(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/AbstractContainerScreenInvoker.java b/src/main/java/dev/hephaestus/glowcase/mixin/AbstractContainerScreenInvoker.java new file mode 100644 index 00000000..dded1de5 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/AbstractContainerScreenInvoker.java @@ -0,0 +1,11 @@ +package dev.hephaestus.glowcase.mixin; + +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.inventory.Slot; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(AbstractContainerScreen.class) +public interface AbstractContainerScreenInvoker { + @Invoker("getHoveredSlot") Slot invokeGetSlotAt(double x, double y); +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/BaseContainerBlockEntityAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/BaseContainerBlockEntityAccessor.java new file mode 100644 index 00000000..26f8c48c --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/BaseContainerBlockEntityAccessor.java @@ -0,0 +1,15 @@ +package dev.hephaestus.glowcase.mixin; + +import net.minecraft.world.LockCode; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(BaseContainerBlockEntity.class) +public interface BaseContainerBlockEntityAccessor { + @Accessor("lockKey") + LockCode glowcase$getLock(); + + @Accessor("lockKey") + void glowcase$setLock(LockCode lock); +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/HandledScreenInvoker.java b/src/main/java/dev/hephaestus/glowcase/mixin/HandledScreenInvoker.java deleted file mode 100644 index 03c77c0c..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/HandledScreenInvoker.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.hephaestus.glowcase.mixin; - -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.screen.slot.Slot; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(HandledScreen.class) -public interface HandledScreenInvoker { - @Invoker Slot invokeGetSlotAt(double x, double y); -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/ContainerLockMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/LockCodeMixin.java similarity index 71% rename from src/main/java/dev/hephaestus/glowcase/mixin/ContainerLockMixin.java rename to src/main/java/dev/hephaestus/glowcase/mixin/LockCodeMixin.java index d724f023..cf3cd646 100644 --- a/src/main/java/dev/hephaestus/glowcase/mixin/ContainerLockMixin.java +++ b/src/main/java/dev/hephaestus/glowcase/mixin/LockCodeMixin.java @@ -1,17 +1,17 @@ package dev.hephaestus.glowcase.mixin; import dev.hephaestus.glowcase.item.LockItem; -import net.minecraft.inventory.ContainerLock; -import net.minecraft.item.ItemStack; +import net.minecraft.world.LockCode; +import net.minecraft.world.item.ItemStack; 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.CallbackInfoReturnable; -@Mixin(ContainerLock.class) -public class ContainerLockMixin { +@Mixin(LockCode.class) +public class LockCodeMixin { @SuppressWarnings("EqualsBetweenInconvertibleTypes") - @Inject(at = @At("HEAD"), method = "canOpen", cancellable = true) + @Inject(at = @At("HEAD"), method = "unlocksWith", cancellable = true) private void canOpen(ItemStack stack, CallbackInfoReturnable cir) { if (LockItem.CONTAINER_LOCK.equals(this)) { cir.setReturnValue(false); diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/LockableContainerBlockEntityAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/LockableContainerBlockEntityAccessor.java deleted file mode 100644 index 3ddfb282..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/LockableContainerBlockEntityAccessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package dev.hephaestus.glowcase.mixin; - -import net.minecraft.block.entity.LockableContainerBlockEntity; -import net.minecraft.inventory.ContainerLock; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(LockableContainerBlockEntity.class) -public interface LockableContainerBlockEntityAccessor { - @Accessor("lock") - ContainerLock glowcase$getLock(); - - @Accessor("lock") - void glowcase$setLock(ContainerLock lock); -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/PlayerEntityMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/PlayerEntityMixin.java deleted file mode 100644 index 51efcb94..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/PlayerEntityMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.hephaestus.glowcase.mixin; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(PlayerEntity.class) -public abstract class PlayerEntityMixin extends LivingEntity { - protected PlayerEntityMixin(EntityType entityType, World world) { - super(entityType, world); - } - - @ModifyReturnValue( - method = "shouldCancelInteraction", - at = @At(value = "RETURN") - ) - private boolean directLockInteraction(boolean original) { - return getEquippedStack(EquipmentSlot.MAINHAND).getItem().equals(Glowcase.LOCK_ITEM.get()) || original; - } -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/PlayerMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/PlayerMixin.java new file mode 100644 index 00000000..bb1c8021 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/PlayerMixin.java @@ -0,0 +1,26 @@ +package dev.hephaestus.glowcase.mixin; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import dev.hephaestus.glowcase.Glowcase; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Player.class) +public abstract class PlayerMixin extends LivingEntity { + protected PlayerMixin(EntityType entityType, Level world) { + super(entityType, world); + } + + @ModifyReturnValue( + method = "isSecondaryUseActive", + at = @At(value = "RETURN") + ) + private boolean directLockInteraction(boolean original) { + return getItemBySlot(EquipmentSlot.MAINHAND).getItem().equals(Glowcase.LOCK_ITEM.get()) || original; + } +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/FontAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/FontAccessor.java new file mode 100644 index 00000000..b66887ff --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/FontAccessor.java @@ -0,0 +1,16 @@ +package dev.hephaestus.glowcase.mixin.client; + +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.font.FontSet; +import net.minecraft.resources.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +/** + * @author Ampflower + * @since ${version} + **/ +@Mixin(Font.class) +public interface FontAccessor { +// @Invoker("getFontSet") FontSet invokeGetFontStorage(Identifier id); +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/GameRendererAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/GameRendererAccessor.java index 3989f068..df5b20f2 100644 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/GameRendererAccessor.java +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/GameRendererAccessor.java @@ -1,7 +1,7 @@ package dev.hephaestus.glowcase.mixin.client; -import net.minecraft.client.render.GameRenderer; -import net.minecraft.client.render.fog.FogRenderer; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.fog.FogRenderer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/GuiMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/GuiMixin.java new file mode 100644 index 00000000..48bc6c82 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/GuiMixin.java @@ -0,0 +1,23 @@ +package dev.hephaestus.glowcase.mixin.client; + +import dev.hephaestus.glowcase.Glowcase; +import dev.hephaestus.glowcase.client.GlowcaseClient; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.resources.Identifier; +import net.minecraft.world.phys.BlockHitResult; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(Gui.class) +public abstract class GuiMixin { + @ModifyArg(method = "renderCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;blitSprite(Lcom/mojang/blaze3d/pipeline/RenderPipeline;Lnet/minecraft/resources/Identifier;IIII)V", ordinal = 0), index = 1) + public Identifier usePickupCrosshair(Identifier original) { + if (Minecraft.getInstance().player != null && Minecraft.getInstance().level != null && Minecraft.getInstance().hitResult instanceof BlockHitResult bhr && Minecraft.getInstance().level.getBlockState(bhr.getBlockPos()).is(Glowcase.ITEM_PROVIDER_BLOCK.get()) && Glowcase.ITEM_PROVIDER_BLOCK.get().canPickup(Minecraft.getInstance().player, bhr.getBlockPos())) { + return GlowcaseClient.PROVIDER_CROSSHAIR_TEXTURE; + } + + return original; + } +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/GuiRendererMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/GuiRendererMixin.java index bcbc4663..5c9c8986 100644 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/GuiRendererMixin.java +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/GuiRendererMixin.java @@ -7,20 +7,21 @@ import com.llamalad7.mixinextras.sugar.ref.LocalRef; import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.systems.RenderPass; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.FilterMode; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.ByteBufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.VertexFormat; import dev.hephaestus.glowcase.client.gui.widget.ingame.SuggestionListWidget; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.Framebuffer; -import net.minecraft.client.gl.PostEffectProcessor; -import net.minecraft.client.gl.RenderPipelines; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.render.GuiRenderer; -import net.minecraft.client.render.BufferBuilder; -import net.minecraft.client.render.BuiltBuffer; -import net.minecraft.client.render.DefaultFramebufferSet; -import net.minecraft.client.render.VertexFormats; -import net.minecraft.client.util.BufferAllocator; +import net.minecraft.client.renderer.LevelTargetBundle; +import net.minecraft.client.renderer.PostChain; +import net.minecraft.client.renderer.RenderPipelines; import org.joml.Matrix3x2f; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -36,19 +37,19 @@ @Mixin(GuiRenderer.class) public abstract class GuiRendererMixin { - @Unique private final GpuBuffer texColorBuffer = RenderSystem.getDevice().createBuffer(() -> "TexColorQuad", GpuBuffer.USAGE_VERTEX | GpuBuffer.USAGE_COPY_DST, 16 * VertexFormats.POSITION_TEXTURE_COLOR.getVertexSize()); + @Unique private final GpuBuffer texColorBuffer = RenderSystem.getDevice().createBuffer(() -> "TexColorQuad", GpuBuffer.USAGE_VERTEX | GpuBuffer.USAGE_COPY_DST, 16 * DefaultVertexFormat.POSITION_TEX_COLOR.getVertexSize()); @Shadow @Final private List draws; - @Shadow @Final private BufferAllocator allocator; + @Shadow @Final private ByteBufferBuilder byteBufferBuilder; - @Shadow protected abstract void render(Supplier nameSupplier, Framebuffer framebuffer, GpuBufferSlice fogBuffer, GpuBufferSlice dynamicTransformsBuffer, GpuBuffer buffer, VertexFormat.IndexType indexType, int from, int to); + @Shadow protected abstract void executeDrawRange(Supplier debugGroup, RenderTarget renderTarget, GpuBufferSlice fog, GpuBufferSlice dynamicTransforms, GpuBuffer buffer, VertexFormat.IndexType indexType, int start, int end); - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/DynamicUniforms;write(Lorg/joml/Matrix4fc;Lorg/joml/Vector4fc;Lorg/joml/Vector3fc;Lorg/joml/Matrix4fc;F)Lcom/mojang/blaze3d/buffers/GpuBufferSlice;", shift = At.Shift.AFTER), method = "renderPreparedDraws") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/DynamicUniforms;writeTransform(Lorg/joml/Matrix4fc;Lorg/joml/Vector4fc;Lorg/joml/Vector3fc;Lorg/joml/Matrix4fc;)Lcom/mojang/blaze3d/buffers/GpuBufferSlice;", shift = At.Shift.AFTER), method = "draw") private void findBlurDraw(GpuBufferSlice fogBuffer, CallbackInfo ci, @Share("suggestionBlurLayer") LocalRef suggestionBlurLayer) { suggestionBlurLayer.set(Integer.MAX_VALUE); for (int i = 0; i < this.draws.size(); i++) { GuiRenderer.Draw draw = draws.get(i); - if (draw.textureSetup().texure0() == SuggestionListWidget.FRAMEBUFFER.getColorAttachmentView() && draw.pipeline() == RenderPipelines.MOJANG_LOGO) { + if (draw.textureSetup().texure0() == SuggestionListWidget.FRAMEBUFFER.getColorTextureView() && draw.pipeline() == RenderPipelines.MOJANG_LOGO) { suggestionBlurLayer.set(i); this.draws.remove(draw); break; @@ -56,21 +57,21 @@ private void findBlurDraw(GpuBufferSlice fogBuffer, CallbackInfo ci, @Share("sug } } - @WrapOperation(at = @At(value = "INVOKE", target = "Ljava/util/List;size()I", ordinal = 2), method = "renderPreparedDraws") + @WrapOperation(at = @At(value = "INVOKE", target = "Ljava/util/List;size()I", ordinal = 2), method = "draw") private int renderBeforeSuggestionBlurAfterBlur(List instance, Operation original, @Share("suggestionBlurLayer") LocalRef suggestionBlurLayer, @Share("afterBlurLimit") LocalRef afterBlurLimit) { Integer i = original.call(instance); afterBlurLimit.set(i); // Save it for mod compat (in case another mod also changes it) return Math.min(suggestionBlurLayer.get(), i); } - @WrapOperation(at = @At(value = "INVOKE", target = "Ljava/util/List;size()I", ordinal = 0), method = "renderPreparedDraws") + @WrapOperation(at = @At(value = "INVOKE", target = "Ljava/util/List;size()I", ordinal = 0), method = "draw") private int renderBeforeSuggestionBlurBeforeBlur(List instance, Operation original, @Share("suggestionBlurLayer") LocalRef suggestionBlurLayer, @Share("beforeBlurLimit") LocalRef beforeBlurLimit) { Integer i = original.call(instance); beforeBlurLimit.set(i); // Save it for mod compat (in case another mod also changes it) return Math.min(suggestionBlurLayer.get(), i); } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/render/GuiRenderer;render(Ljava/util/function/Supplier;Lnet/minecraft/client/gl/Framebuffer;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBuffer;Lcom/mojang/blaze3d/vertex/VertexFormat$IndexType;II)V", ordinal = 0, shift = At.Shift.AFTER), method = "renderPreparedDraws") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/render/GuiRenderer;executeDrawRange(Ljava/util/function/Supplier;Lcom/mojang/blaze3d/pipeline/RenderTarget;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBuffer;Lcom/mojang/blaze3d/vertex/VertexFormat$IndexType;II)V", ordinal = 0, shift = At.Shift.AFTER), method = "draw") private void renderSuggestionsBlurBeforeBlur(GpuBufferSlice fogBuffer, CallbackInfo ci, @Local GpuBuffer gpuBuffer, @Local VertexFormat.IndexType indexType, @Local(ordinal = 1) GpuBufferSlice gpuBufferSlice, @Share("suggestionBlurLayer") LocalRef suggestionBlurLayer, @Share("beforeBlurLimit") LocalRef beforeBlurLimit) { Integer layer = suggestionBlurLayer.get(); if (this.draws.size() > layer) { @@ -78,7 +79,7 @@ private void renderSuggestionsBlurBeforeBlur(GpuBufferSlice fogBuffer, CallbackI } } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/render/GuiRenderer;render(Ljava/util/function/Supplier;Lnet/minecraft/client/gl/Framebuffer;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBuffer;Lcom/mojang/blaze3d/vertex/VertexFormat$IndexType;II)V", ordinal = 1, shift = At.Shift.AFTER), method = "renderPreparedDraws") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/render/GuiRenderer;executeDrawRange(Ljava/util/function/Supplier;Lcom/mojang/blaze3d/pipeline/RenderTarget;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/buffers/GpuBuffer;Lcom/mojang/blaze3d/vertex/VertexFormat$IndexType;II)V", ordinal = 1, shift = At.Shift.AFTER), method = "draw") private void renderSuggestionsBlurAfterBlur(GpuBufferSlice fogBuffer, CallbackInfo ci, @Local GpuBuffer gpuBuffer, @Local VertexFormat.IndexType indexType, @Local(ordinal = 1) GpuBufferSlice gpuBufferSlice, @Share("suggestionBlurLayer") LocalRef suggestionBlurLayer, @Share("afterBlurLimit") LocalRef afterBlurLimit) { Integer layer = suggestionBlurLayer.get(); if (this.draws.size() > layer) { @@ -88,68 +89,68 @@ private void renderSuggestionsBlurAfterBlur(GpuBufferSlice fogBuffer, CallbackIn @Unique private void renderSuggestionsBlur(Supplier nameSupplier, GpuBufferSlice fogBuffer, GpuBuffer indexBuffer, VertexFormat.IndexType indexType, GpuBufferSlice dynamicTransformsBuffer, int from, int to) { - RenderSystem.getDevice().createCommandEncoder().clearColorTexture(SuggestionListWidget.FRAMEBUFFER.getColorAttachment(), 0); + RenderSystem.getDevice().createCommandEncoder().clearColorTexture(SuggestionListWidget.FRAMEBUFFER.getColorTexture(), 0); - MinecraftClient client = MinecraftClient.getInstance(); - Framebuffer framebuffer = SuggestionListWidget.FRAMEBUFFER; - Framebuffer clientFramebuffer = client.getFramebuffer(); - if (framebuffer.textureWidth != clientFramebuffer.textureWidth || framebuffer.textureHeight != clientFramebuffer.textureHeight) { - framebuffer.resize(clientFramebuffer.textureWidth, clientFramebuffer.textureHeight); + Minecraft client = Minecraft.getInstance(); + RenderTarget framebuffer = SuggestionListWidget.FRAMEBUFFER; + RenderTarget clientFramebuffer = client.getMainRenderTarget(); + if (framebuffer.width != clientFramebuffer.width || framebuffer.height != clientFramebuffer.height) { + framebuffer.resize(clientFramebuffer.width, clientFramebuffer.height); - int width = client.getWindow().getScaledWidth(); - int height = client.getWindow().getScaledHeight(); + int width = client.getWindow().getGuiScaledWidth(); + int height = client.getWindow().getGuiScaledHeight(); Matrix3x2f matrices = new Matrix3x2f(); - BufferBuilder bufferBuilder = new BufferBuilder(this.allocator, VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR); - bufferBuilder.vertex(matrices, 0, 0, from).texture(0, 0).color(0XFFFFFFFF); - bufferBuilder.vertex(matrices, 0, height, from).texture(0, 1).color(0XFFFFFFFF); - bufferBuilder.vertex(matrices, width, height, from).texture(1, 1).color(0XFFFFFFFF); - bufferBuilder.vertex(matrices, width, 0, from).texture(1, 0).color(0XFFFFFFFF); - - try (BuiltBuffer builtBuffer = bufferBuilder.end()) { - RenderSystem.getDevice().createCommandEncoder().writeToBuffer(texColorBuffer.slice(), builtBuffer.getBuffer()); + BufferBuilder bufferBuilder = new BufferBuilder(this.byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); + bufferBuilder.addVertexWith2DPose(matrices, 0, 0).setUv(0, 0).setColor(0XFFFFFFFF); + bufferBuilder.addVertexWith2DPose(matrices, 0, height).setUv(0, 1).setColor(0XFFFFFFFF); + bufferBuilder.addVertexWith2DPose(matrices, width, height).setUv(1, 1).setColor(0XFFFFFFFF); + bufferBuilder.addVertexWith2DPose(matrices, width, 0).setUv(1, 0).setColor(0XFFFFFFFF); + + try (MeshData builtBuffer = bufferBuilder.buildOrThrow()) { + RenderSystem.getDevice().createCommandEncoder().writeToBuffer(texColorBuffer.slice(), builtBuffer.vertexBuffer()); } } copyTexture(clientFramebuffer, framebuffer, dynamicTransformsBuffer); - if ((float) client.options.getMenuBackgroundBlurrinessValue() >= 1.0F) { + if ((float) client.options.getMenuBackgroundBlurriness() >= 1.0F) { renderBlur(framebuffer); } - this.render(nameSupplier, clientFramebuffer, fogBuffer, dynamicTransformsBuffer, indexBuffer, indexType, from, to); + this.executeDrawRange(nameSupplier, clientFramebuffer, fogBuffer, dynamicTransformsBuffer, indexBuffer, indexType, from, to); } @Unique - public void copyTexture(Framebuffer sourceBuffer, Framebuffer targetBuffer, GpuBufferSlice dynamicTransformsBuffer) { + public void copyTexture(RenderTarget sourceBuffer, RenderTarget targetBuffer, GpuBufferSlice dynamicTransformsBuffer) { RenderSystem.assertOnRenderThread(); - RenderSystem.ShapeIndexBuffer shapeIndexBuffer = RenderSystem.getSequentialBuffer(VertexFormat.DrawMode.QUADS); - GpuBuffer indexBuffer = shapeIndexBuffer.getIndexBuffer(6); + RenderSystem.AutoStorageIndexBuffer shapeIndexBuffer = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS); + GpuBuffer indexBuffer = shapeIndexBuffer.getBuffer(6); try (RenderPass renderPass = RenderSystem.getDevice().createCommandEncoder().createRenderPass( () -> "Copy render target", - targetBuffer.getColorAttachmentView(), OptionalInt.empty() + targetBuffer.getColorTextureView(), OptionalInt.empty() )) { renderPass.setPipeline(RenderPipelines.GUI_TEXTURED); RenderSystem.bindDefaultUniforms(renderPass); renderPass.setUniform("DynamicTransforms", dynamicTransformsBuffer); - renderPass.setIndexBuffer(indexBuffer, shapeIndexBuffer.getIndexType()); + renderPass.setIndexBuffer(indexBuffer, shapeIndexBuffer.type()); renderPass.setVertexBuffer(0, texColorBuffer); - renderPass.bindSampler("Sampler0", sourceBuffer.getColorAttachmentView()); + renderPass.bindTexture("Sampler0", sourceBuffer.getColorTextureView(), RenderSystem.getSamplerCache().getClampToEdge(FilterMode.NEAREST)); renderPass.drawIndexed(0, 0, 6, 1); } } - @Inject(at = @At("RETURN"), method = "renderPreparedDraws") + @Inject(at = @At("RETURN"), method = "draw") private void decrementPool(GpuBufferSlice fogBuffer, CallbackInfo ci) { - SuggestionListWidget.POOL.decrementLifespan(); + SuggestionListWidget.POOL.endFrame(); } @Unique - public void renderBlur(Framebuffer framebuffer) { - PostEffectProcessor postEffectProcessor = MinecraftClient.getInstance().getShaderLoader().loadPostEffect(SuggestionListWidget.BLUR_ID, DefaultFramebufferSet.MAIN_ONLY); + public void renderBlur(RenderTarget framebuffer) { + PostChain postEffectProcessor = Minecraft.getInstance().getShaderManager().getPostChain(SuggestionListWidget.BLUR_ID, LevelTargetBundle.MAIN_TARGETS); if (postEffectProcessor != null) { - postEffectProcessor.render(framebuffer, SuggestionListWidget.POOL); + postEffectProcessor.process(framebuffer, SuggestionListWidget.POOL); } } } diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/ItemInHandRendererMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/ItemInHandRendererMixin.java new file mode 100644 index 00000000..59272f64 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/ItemInHandRendererMixin.java @@ -0,0 +1,39 @@ +package dev.hephaestus.glowcase.mixin.client; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mojang.blaze3d.vertex.PoseStack; +import dev.hephaestus.glowcase.client.render.item.ItemHandRenderer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.renderer.ItemInHandRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; +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(ItemInHandRenderer.class) +public class ItemInHandRendererMixin { + @Inject(method = "renderMap", at = @At("HEAD"), cancellable = true) + void glowcase$renderFirstPersonTablet(PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, ItemStack itemStack, CallbackInfo ci) { + if (Minecraft.getInstance().player == null || Minecraft.getInstance().level == null) return; + + @Nullable ItemHandRenderer renderer = ItemHandRenderer.getRenderer(itemStack); + if (renderer == null) return; + + // FIXME 26.1 +// renderer.render(poseStack, submitNodeCollector, lightCoords, itemStack); + ci.cancel(); + } + + // FIXME 26.1 +// @ModifyExpressionValue(method = "renderArmWithItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;has(Lnet/minecraft/core/component/DataComponentType;)Z", ordinal = 0)) +// private boolean glowcase$enableFirstPersonTabletRendering(boolean original, AbstractClientPlayer player, float tickDelta, float pitch, InteractionHand hand, float swingProgress, ItemStack stack, float equipProgress, PoseStack matrices, MultiBufferSource vertexConsumers, int light) { +// @Nullable ItemHandRenderer renderer = ItemHandRenderer.getRenderer(stack); +// return original || (renderer != null && renderer.visible(stack)); +// } +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/KeyboardMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/KeyboardHandlerMixin.java similarity index 58% rename from src/main/java/dev/hephaestus/glowcase/mixin/client/KeyboardMixin.java rename to src/main/java/dev/hephaestus/glowcase/mixin/client/KeyboardHandlerMixin.java index 79525454..d44c4faf 100644 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/KeyboardMixin.java +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/KeyboardHandlerMixin.java @@ -2,21 +2,20 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.hephaestus.glowcase.client.gui.screen.ingame.TextBlockEditScreen; -import net.minecraft.client.Keyboard; -import net.minecraft.client.MinecraftClient; +import net.minecraft.client.KeyboardHandler; +import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -@Mixin(Keyboard.class) -public class KeyboardMixin { - +@Mixin(KeyboardHandler.class) +public class KeyboardHandlerMixin { @ModifyExpressionValue( - method = "onKey", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/NarratorManager;isActive()Z") + method = "keyPress", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/GameNarrator;isActive()Z") ) private boolean preventNarratorToggleOnTextBlockScreen(boolean original) { //prevents the narrator from being toggled when pressing "ctrl+b" to hotkey bold formatting in the text block - return original && !(MinecraftClient.getInstance().currentScreen instanceof TextBlockEditScreen); + return original && !(Minecraft.getInstance().screen instanceof TextBlockEditScreen); } } diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/MixinHeldItemRenderer.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/MixinHeldItemRenderer.java deleted file mode 100644 index ed46160c..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/MixinHeldItemRenderer.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.hephaestus.glowcase.mixin.client; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.hephaestus.glowcase.client.render.item.ItemHandRenderer; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.item.HeldItemRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Hand; -import org.jetbrains.annotations.Nullable; -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(HeldItemRenderer.class) -public class MixinHeldItemRenderer { - @Inject(method = "renderFirstPersonMap", at = @At("HEAD"), cancellable = true) - void glowcase$renderFirstPersonTablet(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, ItemStack stack, CallbackInfo ci) { - if (MinecraftClient.getInstance().player == null || MinecraftClient.getInstance().world == null) return; - - @Nullable ItemHandRenderer renderer = ItemHandRenderer.getRenderer(stack); - if (renderer == null) return; - - renderer.render(matrices, vertexConsumers, light, stack); - ci.cancel(); - } - - @ModifyExpressionValue(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;contains(Lnet/minecraft/component/ComponentType;)Z", ordinal = 0)) - private boolean glowcase$enableFirstPersonTabletRendering(boolean original, AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack stack, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) { - @Nullable ItemHandRenderer renderer = ItemHandRenderer.getRenderer(stack); - return original || (renderer != null && renderer.visible(stack)); - } -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/MixinInGameHud.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/MixinInGameHud.java deleted file mode 100644 index b51d34de..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/MixinInGameHud.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.hephaestus.glowcase.mixin.client; - -import dev.hephaestus.glowcase.Glowcase; -import dev.hephaestus.glowcase.client.GlowcaseClient; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -@Mixin(InGameHud.class) -public abstract class MixinInGameHud { - @ModifyArg(method = "renderCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lcom/mojang/blaze3d/pipeline/RenderPipeline;Lnet/minecraft/util/Identifier;IIII)V", ordinal = 0), index = 1) - public Identifier usePickupCrosshair(Identifier original) { - if (MinecraftClient.getInstance().player != null && MinecraftClient.getInstance().world != null && MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult bhr && MinecraftClient.getInstance().world.getBlockState(bhr.getBlockPos()).isOf(Glowcase.ITEM_PROVIDER_BLOCK.get()) && Glowcase.ITEM_PROVIDER_BLOCK.get().canPickup(MinecraftClient.getInstance().player, bhr.getBlockPos())) { - return GlowcaseClient.PROVIDER_CROSSHAIR_TEXTURE; - } - - return original; - } -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/MultiPhaseRenderLayerAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/MultiPhaseRenderLayerAccessor.java deleted file mode 100644 index a10f6fe6..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/MultiPhaseRenderLayerAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.hephaestus.glowcase.mixin.client; - -import com.mojang.blaze3d.pipeline.RenderPipeline; -import net.minecraft.client.render.RenderLayer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(RenderLayer.MultiPhase.class) -public interface MultiPhaseRenderLayerAccessor { - @Accessor RenderPipeline getPipeline(); - @Accessor RenderLayer.MultiPhaseParameters getPhases(); -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/RenderLayerMultiPhaseParametersAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/RenderLayerMultiPhaseParametersAccessor.java deleted file mode 100644 index dc83cd67..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/RenderLayerMultiPhaseParametersAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.hephaestus.glowcase.mixin.client; - -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(RenderLayer.MultiPhaseParameters.class) -public interface RenderLayerMultiPhaseParametersAccessor { - @Accessor RenderPhase.Target getTarget(); -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/TextRendererAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/TextRendererAccessor.java deleted file mode 100644 index 115d457a..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/TextRendererAccessor.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.hephaestus.glowcase.mixin.client; - -import net.minecraft.client.font.FontStorage; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -/** - * @author Ampflower - * @since ${version} - **/ -@Mixin(TextRenderer.class) -public interface TextRendererAccessor { - @Invoker FontStorage invokeGetFontStorage(Identifier id); -} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/TextureManagerAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/TextureManagerAccessor.java index 5dc4301b..d35eba3c 100644 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/TextureManagerAccessor.java +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/TextureManagerAccessor.java @@ -1,13 +1,13 @@ package dev.hephaestus.glowcase.mixin.client; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.resource.ResourceManager; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.server.packs.resources.ResourceManager; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(TextureManager.class) public interface TextureManagerAccessor { - @Accessor("resourceContainer") + @Accessor("resourceManager") ResourceManager glowcase$getResourceManager(); } diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundEngineMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundEngineMixin.java new file mode 100644 index 00000000..f1128917 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundEngineMixin.java @@ -0,0 +1,40 @@ +package dev.hephaestus.glowcase.mixin.client.sound; + +import dev.hephaestus.glowcase.client.util.SoundPlayerProxy; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; +import java.util.Map; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.resources.sounds.TickableSoundInstance; +import net.minecraft.client.sounds.SoundEngine; + +/** + * @author Ampflower + **/ +@Mixin(SoundEngine.class) +public abstract class SoundEngineMixin implements SoundPlayerProxy { + @Shadow + public abstract boolean isActive(final SoundInstance sound); + + @Shadow + @Final + private Map queuedSounds; + + @Shadow + @Final + private List queuedTickableSounds; + + @Override + public boolean glowcase$isQueued(final SoundInstance sound) { + return this.queuedSounds.containsKey(sound) || + this.queuedTickableSounds.contains(sound); + } + + @Override + public boolean glowcase$isQueuedOrPlaying(final SoundInstance sound) { + return this.isActive(sound) || this.glowcase$isQueued(sound); + } +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundManagerMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundManagerMixin.java index fdcb3d70..abf44741 100644 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundManagerMixin.java +++ b/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundManagerMixin.java @@ -1,31 +1,31 @@ package dev.hephaestus.glowcase.mixin.client.sound; import dev.hephaestus.glowcase.client.util.SoundPlayerProxy; -import net.minecraft.client.sound.SoundInstance; -import net.minecraft.client.sound.SoundManager; -import net.minecraft.client.sound.SoundSystem; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.sounds.SoundEngine; +import net.minecraft.client.sounds.SoundManager; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; /** * @author Ampflower - * @implNote Functions here generally need to proxy to the {@link SoundSystem sound system}. - * @see SoundSystemMixin + * @implNote Functions here generally need to proxy to the {@link SoundEngine sound system}. + * @see SoundEngineMixin **/ @Mixin(SoundManager.class) public class SoundManagerMixin implements SoundPlayerProxy { @Shadow @Final - private SoundSystem soundSystem; + private SoundEngine soundEngine; @Override public boolean glowcase$isQueued(final SoundInstance sound) { - return ((SoundPlayerProxy) this.soundSystem).glowcase$isQueued(sound); + return ((SoundPlayerProxy) this.soundEngine).glowcase$isQueued(sound); } @Override public boolean glowcase$isQueuedOrPlaying(final SoundInstance sound) { - return ((SoundPlayerProxy) this.soundSystem).glowcase$isQueuedOrPlaying(sound); + return ((SoundPlayerProxy) this.soundEngine).glowcase$isQueuedOrPlaying(sound); } } diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundSystemMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundSystemMixin.java deleted file mode 100644 index 252499fa..00000000 --- a/src/main/java/dev/hephaestus/glowcase/mixin/client/sound/SoundSystemMixin.java +++ /dev/null @@ -1,40 +0,0 @@ -package dev.hephaestus.glowcase.mixin.client.sound; - -import dev.hephaestus.glowcase.client.util.SoundPlayerProxy; -import net.minecraft.client.sound.SoundInstance; -import net.minecraft.client.sound.SoundSystem; -import net.minecraft.client.sound.TickableSoundInstance; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.List; -import java.util.Map; - -/** - * @author Ampflower - **/ -@Mixin(SoundSystem.class) -public abstract class SoundSystemMixin implements SoundPlayerProxy { - @Shadow - public abstract boolean isPlaying(final SoundInstance sound); - - @Shadow - @Final - private Map soundStartTicks; - - @Shadow - @Final - private List soundsToPlayNextTick; - - @Override - public boolean glowcase$isQueued(final SoundInstance sound) { - return this.soundStartTicks.containsKey(sound) || - this.soundsToPlayNextTick.contains(sound); - } - - @Override - public boolean glowcase$isQueuedOrPlaying(final SoundInstance sound) { - return this.isPlaying(sound) || this.glowcase$isQueued(sound); - } -} diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditBlockEntity.java index 6aa3f571..35156fd4 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditBlockEntity.java @@ -3,31 +3,31 @@ import dev.hephaestus.glowcase.block.GlowcaseBlock; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.ChunkPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.entity.BlockEntity; -public interface C2SEditBlockEntity extends CustomPayload { +public interface C2SEditBlockEntity extends CustomPacketPayload { BlockPos pos(); - void receive(ServerWorld world, BlockEntity blockEntity); + void receive(ServerLevel world, BlockEntity blockEntity); default void receive(ServerPlayNetworking.Context context) { if (!canEdit(context.player())) return; - receive(context.player().getWorld(), context.player().getWorld().getBlockEntity(this.pos())); + receive(context.player().level(), context.player().level().getBlockEntity(this.pos())); } default void send() { ClientPlayNetworking.send(this); } - default boolean canEdit(ServerPlayerEntity player) { - if (!player.getWorld().isChunkLoaded(ChunkPos.toLong(pos()))) return false; - if (player.squaredDistanceTo(pos().toCenterPos()) > (12 * 12)) return false; - return player.getWorld().getBlockState(pos()).getBlock() instanceof GlowcaseBlock block && GlowcaseBlock.canEditGlowcase(player, pos()); + default boolean canEdit(ServerPlayer player) { + if (!player.level().areEntitiesLoaded(ChunkPos.pack(pos()))) return false; + if (player.distanceToSqr(pos().getCenter()) > (12 * 12)) return false; + return player.level().getBlockState(pos()).getBlock() instanceof GlowcaseBlock block && GlowcaseBlock.canEditGlowcase(player, pos()); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditConfigLinkBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditConfigLinkBlock.java index e7dc1bcf..0fcf33c1 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditConfigLinkBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditConfigLinkBlock.java @@ -2,34 +2,34 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ConfigLinkBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditConfigLinkBlock(BlockPos pos, String title, String url) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.configlink.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditConfigLinkBlock::pos, - PacketCodecs.STRING, C2SEditConfigLinkBlock::title, - PacketCodecs.STRING, C2SEditConfigLinkBlock::url, + public static final Type ID = new Type<>(Glowcase.id("channel.configlink.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditConfigLinkBlock::pos, + ByteBufCodecs.STRING_UTF8, C2SEditConfigLinkBlock::title, + ByteBufCodecs.STRING_UTF8, C2SEditConfigLinkBlock::url, C2SEditConfigLinkBlock::new ); public static C2SEditConfigLinkBlock of(ConfigLinkBlockEntity be) { - return new C2SEditConfigLinkBlock(be.getPos(), be.getTitle(), be.getUrl()); + return new C2SEditConfigLinkBlock(be.getBlockPos(), be.getTitle(), be.getUrl()); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof ConfigLinkBlockEntity be)) return; if (this.title().length() <= ConfigLinkBlockEntity.TITLE_MAX_LENGTH) { be.setTitle(this.title()); diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditDisplayBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditDisplayBlock.java index c01aee01..88cfe44f 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditDisplayBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditDisplayBlock.java @@ -2,13 +2,13 @@ import dev.hephaestus.glowcase.block.entity.DisplayBlockEntity; import dev.hephaestus.glowcase.util.DisplayBlockSettings; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.server.world.ServerWorld; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public interface C2SEditDisplayBlock { DisplayBlockSettings settings(); - default void receive(ServerWorld world, BlockEntity blockEntity) { + default void receive(ServerLevel world, BlockEntity blockEntity) { if ((blockEntity instanceof DisplayBlockEntity be)) { be.loadSettings(settings()); } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditEntityDisplayBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditEntityDisplayBlock.java index 49b283f9..bce1d00d 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditEntityDisplayBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditEntityDisplayBlock.java @@ -3,32 +3,32 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.DisplayBlockEntity; import dev.hephaestus.glowcase.util.DisplayBlockSettings; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditEntityDisplayBlock(BlockPos pos, DisplayBlockSettings settings) implements C2SEditBlockEntity, C2SEditDisplayBlock { - public static final Id ID = new Id<>(Glowcase.id("channel.entity_display")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditEntityDisplayBlock::pos, + public static final Type ID = new Type<>(Glowcase.id("channel.entity_display")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditEntityDisplayBlock::pos, DisplayBlockSettings.PACKET_CODEC, C2SEditEntityDisplayBlock::settings, C2SEditEntityDisplayBlock::new ); public static C2SEditEntityDisplayBlock of(DisplayBlockEntity be) { - return new C2SEditEntityDisplayBlock(be.getPos(), be.toSettings()); + return new C2SEditEntityDisplayBlock(be.getBlockPos(), be.toSettings()); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { C2SEditDisplayBlock.super.receive(world, blockEntity); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditHyperlinkBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditHyperlinkBlock.java index e7856bfc..dbe5f2f8 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditHyperlinkBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditHyperlinkBlock.java @@ -2,34 +2,34 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditHyperlinkBlock(BlockPos pos, String title, String url) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.hyperlink.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditHyperlinkBlock::pos, - PacketCodecs.STRING, C2SEditHyperlinkBlock::title, - PacketCodecs.STRING, C2SEditHyperlinkBlock::url, + public static final Type ID = new Type<>(Glowcase.id("channel.hyperlink.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditHyperlinkBlock::pos, + ByteBufCodecs.STRING_UTF8, C2SEditHyperlinkBlock::title, + ByteBufCodecs.STRING_UTF8, C2SEditHyperlinkBlock::url, C2SEditHyperlinkBlock::new ); public static C2SEditHyperlinkBlock of(HyperlinkBlockEntity be) { - return new C2SEditHyperlinkBlock(be.getPos(), be.getTitle(), be.getUrl()); + return new C2SEditHyperlinkBlock(be.getBlockPos(), be.getTitle(), be.getUrl()); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof HyperlinkBlockEntity be)) return; if (this.title().length() <= HyperlinkBlockEntity.TITLE_MAX_LENGTH) { be.setTitle(this.title()); diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemAcceptorBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemAcceptorBlock.java index 911e28b4..284425f8 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemAcceptorBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemAcceptorBlock.java @@ -2,38 +2,38 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ItemAcceptorBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.Identifier; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditItemAcceptorBlock(BlockPos pos, Identifier item, int count, int pulse, boolean isItemTag, ItemAcceptorBlockEntity.OutputDirection outputDirection) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.item_acceptor.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditItemAcceptorBlock::pos, - Identifier.PACKET_CODEC, C2SEditItemAcceptorBlock::item, - PacketCodecs.INTEGER, C2SEditItemAcceptorBlock::count, - PacketCodecs.INTEGER, C2SEditItemAcceptorBlock::pulse, - PacketCodecs.BOOLEAN, C2SEditItemAcceptorBlock::isItemTag, - PacketCodecs.BYTE.xmap(index -> ItemAcceptorBlockEntity.OutputDirection.values()[index], outputDirection -> (byte) outputDirection.ordinal()), C2SEditItemAcceptorBlock::outputDirection, + public static final Type ID = new Type<>(Glowcase.id("channel.item_acceptor.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditItemAcceptorBlock::pos, + Identifier.STREAM_CODEC, C2SEditItemAcceptorBlock::item, + ByteBufCodecs.INT, C2SEditItemAcceptorBlock::count, + ByteBufCodecs.INT, C2SEditItemAcceptorBlock::pulse, + ByteBufCodecs.BOOL, C2SEditItemAcceptorBlock::isItemTag, + ByteBufCodecs.BYTE.map(index -> ItemAcceptorBlockEntity.OutputDirection.values()[index], outputDirection -> (byte) outputDirection.ordinal()), C2SEditItemAcceptorBlock::outputDirection, C2SEditItemAcceptorBlock::new ); public static C2SEditItemAcceptorBlock of(ItemAcceptorBlockEntity be) { - return new C2SEditItemAcceptorBlock(be.getPos(), be.getItem(), be.count, be.pulse, be.isItemTag, be.outputDirection); + return new C2SEditItemAcceptorBlock(be.getBlockPos(), be.getItem(), be.count, be.pulse, be.isItemTag, be.outputDirection); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof ItemAcceptorBlockEntity be)) return; be.setItem(this.item()); @@ -42,6 +42,6 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { be.isItemTag = this.isItemTag(); be.outputDirection = this.outputDirection(); - be.markDirty(); + be.setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemDisplayBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemDisplayBlock.java index c7eb9c13..84a8db2e 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemDisplayBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemDisplayBlock.java @@ -3,33 +3,33 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.DisplayBlockEntity; import dev.hephaestus.glowcase.util.DisplayBlockSettings; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditItemDisplayBlock(BlockPos pos, DisplayBlockSettings settings) implements C2SEditBlockEntity, C2SEditDisplayBlock { - public static final Id ID = new Id<>(Glowcase.id("channel.item_display")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditItemDisplayBlock::pos, + public static final Type ID = new Type<>(Glowcase.id("channel.item_display")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditItemDisplayBlock::pos, DisplayBlockSettings.PACKET_CODEC, C2SEditItemDisplayBlock::settings, C2SEditItemDisplayBlock::new ); public static C2SEditEntityDisplayBlock of(DisplayBlockEntity be) { - return new C2SEditEntityDisplayBlock(be.getPos(), be.toSettings()); + return new C2SEditEntityDisplayBlock(be.getBlockPos(), be.toSettings()); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { C2SEditDisplayBlock.super.receive(world, blockEntity); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemProviderBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemProviderBlock.java index 61a732b3..2bc16ea0 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemProviderBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditItemProviderBlock.java @@ -2,34 +2,34 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ItemProviderBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditItemProviderBlock(BlockPos pos, ItemProviderBlockEntity.GivesItem givesItem, long cooldown) implements C2SEditBlockEntity { - public static final CustomPayload.Id ID = new CustomPayload.Id<>(Glowcase.id("channel.item_provider")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditItemProviderBlock::pos, - PacketCodecs.BYTE.xmap(index -> ItemProviderBlockEntity.GivesItem.values()[index], givesItem -> (byte) givesItem.ordinal()), C2SEditItemProviderBlock::givesItem, - PacketCodecs.VAR_LONG, C2SEditItemProviderBlock::cooldown, + public static final CustomPacketPayload.Type ID = new CustomPacketPayload.Type<>(Glowcase.id("channel.item_provider")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditItemProviderBlock::pos, + ByteBufCodecs.BYTE.map(index -> ItemProviderBlockEntity.GivesItem.values()[index], givesItem -> (byte) givesItem.ordinal()), C2SEditItemProviderBlock::givesItem, + ByteBufCodecs.VAR_LONG, C2SEditItemProviderBlock::cooldown, C2SEditItemProviderBlock::new ); public static C2SEditItemProviderBlock of(ItemProviderBlockEntity be) { - return new C2SEditItemProviderBlock(be.getPos(), be.getGivesItem(), be.cooldown); + return new C2SEditItemProviderBlock(be.getBlockPos(), be.getGivesItem(), be.cooldown); } @Override - public CustomPayload.Id getId() { + public CustomPacketPayload.Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof ItemProviderBlockEntity be)) return; be.setGivesItem(this.givesItem()); be.cooldown = this.cooldown; diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditNoteItem.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditNoteItem.java index 6afdb38b..d30656bf 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditNoteItem.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditNoteItem.java @@ -4,29 +4,29 @@ import dev.hephaestus.glowcase.item.component.NoteComponent; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.item.ItemStack; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.item.ItemStack; -public record C2SEditNoteItem(NoteComponent noteComponent) implements CustomPayload { - public static final Id ID = new Id<>(Glowcase.id("channel.note_item")); +public record C2SEditNoteItem(NoteComponent noteComponent) implements CustomPacketPayload { + public static final Type ID = new Type<>(Glowcase.id("channel.note_item")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - NoteComponent.TYPE.getPacketCodec(), C2SEditNoteItem::noteComponent, + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + NoteComponent.TYPE.streamCodec(), C2SEditNoteItem::noteComponent, C2SEditNoteItem::new ); @Override - public Id getId() { + public Type type() { return ID; } public void receive(ServerPlayNetworking.Context context) { - ItemStack stack = context.player().getMainHandStack(); - if (!(stack.isOf(Glowcase.NOTE_ITEM.get()))) return; + ItemStack stack = context.player().getMainHandItem(); + if (!(stack.is(Glowcase.NOTE_ITEM.get()))) return; - if (stack.contains(Glowcase.NOTE_COMPONENT.get())) { + if (stack.has(Glowcase.NOTE_COMPONENT.get())) { NoteComponent existingNote = stack.get(Glowcase.NOTE_COMPONENT.get()); assert existingNote != null; if (existingNote.title().isPresent()) diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditOutlineBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditOutlineBlock.java index bdbf0848..f1c3b7bf 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditOutlineBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditOutlineBlock.java @@ -2,49 +2,49 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.OutlineBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3i; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditOutlineBlock(BlockPos pos, Vec3i offset, Vec3i scale, int color) implements C2SEditBlockEntity { - public static final PacketCodec VEC3I = PacketCodec.tuple( - PacketCodecs.INTEGER, Vec3i::getX, - PacketCodecs.INTEGER, Vec3i::getY, - PacketCodecs.INTEGER, Vec3i::getZ, + public static final StreamCodec VEC3I = StreamCodec.composite( + ByteBufCodecs.INT, Vec3i::getX, + ByteBufCodecs.INT, Vec3i::getY, + ByteBufCodecs.INT, Vec3i::getZ, Vec3i::new ); - public static final Id ID = new Id<>(Glowcase.id("channel.outline.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditOutlineBlock::pos, + public static final Type ID = new Type<>(Glowcase.id("channel.outline.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditOutlineBlock::pos, VEC3I, C2SEditOutlineBlock::offset, VEC3I, C2SEditOutlineBlock::scale, - PacketCodecs.INTEGER, C2SEditOutlineBlock::color, + ByteBufCodecs.INT, C2SEditOutlineBlock::color, C2SEditOutlineBlock::new ); public static C2SEditOutlineBlock of(OutlineBlockEntity be) { - return new C2SEditOutlineBlock(be.getPos(), be.offset, be.scale, be.color); + return new C2SEditOutlineBlock(be.getBlockPos(), be.offset, be.scale, be.color); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof OutlineBlockEntity be)) return; be.offset = this.offset(); be.scale = this.scale(); be.color = this.color(); - be.markDirty(); + be.setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditParticleDisplayBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditParticleDisplayBlock.java index 0deeb832..0f8d3b21 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditParticleDisplayBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditParticleDisplayBlock.java @@ -4,40 +4,40 @@ import dev.hephaestus.glowcase.block.entity.ParticleDisplayBlockEntity; import dev.hephaestus.glowcase.util.DeviatedInteger; import dev.hephaestus.glowcase.util.DeviatedVec3d; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.particle.ParticleEffect; -import net.minecraft.particle.ParticleTypes; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditParticleDisplayBlock( - ParticleEffect particle, + ParticleOptions particle, DeviatedInteger count, DeviatedVec3d velocity, DeviatedVec3d position, DeviatedInteger tickRate, BlockPos blockPos ) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.particle_display.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - ParticleTypes.PACKET_CODEC, C2SEditParticleDisplayBlock::particle, + public static final Type ID = new Type<>(Glowcase.id("channel.particle_display.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + ParticleTypes.STREAM_CODEC, C2SEditParticleDisplayBlock::particle, DeviatedInteger.PACKET_CODEC, C2SEditParticleDisplayBlock::count, DeviatedVec3d.PACKET_CODEC, C2SEditParticleDisplayBlock::velocity, DeviatedVec3d.PACKET_CODEC, C2SEditParticleDisplayBlock::position, DeviatedInteger.PACKET_CODEC, C2SEditParticleDisplayBlock::tickRate, - BlockPos.PACKET_CODEC, C2SEditParticleDisplayBlock::blockPos, + BlockPos.STREAM_CODEC, C2SEditParticleDisplayBlock::blockPos, C2SEditParticleDisplayBlock::new ); public static C2SEditParticleDisplayBlock of(ParticleDisplayBlockEntity be) { - return new C2SEditParticleDisplayBlock(be.particle, be.count, be.velocity, be.position, be.tickRate, be.getPos()); + return new C2SEditParticleDisplayBlock(be.particle, be.count, be.velocity, be.position, be.tickRate, be.getBlockPos()); } @Override - public Id getId() { + public Type type() { return ID; } @@ -47,7 +47,7 @@ public BlockPos pos() { } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof ParticleDisplayBlockEntity be)) return; be.particle = this.particle(); @@ -56,6 +56,6 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { be.position = this.position(); be.tickRate = this.tickRate(); - be.markDirty(); + be.setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditPopupBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditPopupBlock.java index 612cf930..74b9ab29 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditPopupBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditPopupBlock.java @@ -4,41 +4,40 @@ import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity; import dev.hephaestus.glowcase.block.entity.PopupBlockEntity; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.Text; -import net.minecraft.text.TextCodecs; -import net.minecraft.util.math.BlockPos; - import java.util.ArrayList; import java.util.List; - -public record C2SEditPopupBlock(BlockPos pos, String title, List lines, TextBlockEntity.TextAlignment alignment, int color) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.popup_block")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditPopupBlock::pos, - PacketCodecs.STRING, C2SEditPopupBlock::title, - PacketCodecs.collection(ArrayList::new, TextCodecs.REGISTRY_PACKET_CODEC), C2SEditPopupBlock::lines, - PacketCodecs.BYTE.xmap(index -> TextBlockEntity.TextAlignment.values()[index], textAlignment -> (byte) textAlignment.ordinal()), C2SEditPopupBlock::alignment, - PacketCodecs.INTEGER, C2SEditPopupBlock::color, +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; + +public record C2SEditPopupBlock(BlockPos pos, String title, List lines, TextBlockEntity.TextAlignment alignment, int color) implements C2SEditBlockEntity { + public static final Type ID = new Type<>(Glowcase.id("channel.popup_block")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditPopupBlock::pos, + ByteBufCodecs.STRING_UTF8, C2SEditPopupBlock::title, + ByteBufCodecs.collection(ArrayList::new, ComponentSerialization.STREAM_CODEC), C2SEditPopupBlock::lines, + ByteBufCodecs.BYTE.map(index -> TextBlockEntity.TextAlignment.values()[index], textAlignment -> (byte) textAlignment.ordinal()), C2SEditPopupBlock::alignment, + ByteBufCodecs.INT, C2SEditPopupBlock::color, C2SEditPopupBlock::new ); public static C2SEditPopupBlock of(PopupBlockEntity be) { - return new C2SEditPopupBlock(be.getPos(), be.title, be.lines, be.textAlignment, be.color); + return new C2SEditPopupBlock(be.getBlockPos(), be.title, be.lines, be.textAlignment, be.color); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof PopupBlockEntity be)) return; if (this.title().length() <= HyperlinkBlockEntity.TITLE_MAX_LENGTH) { @@ -48,6 +47,6 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { be.textAlignment = this.alignment(); be.color = this.color(); - be.markDirty(); + be.setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditRecipeBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditRecipeBlock.java index 0c873980..525be8a0 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditRecipeBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditRecipeBlock.java @@ -3,36 +3,36 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.RecipeBlockEntity; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditRecipeBlock(BlockPos pos, String recipe, TextBlockEntity.ZOffset offset, float rotationX, float rotationY) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.recipe.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditRecipeBlock::pos, - PacketCodecs.STRING, C2SEditRecipeBlock::recipe, - PacketCodecs.INTEGER.xmap(index -> TextBlockEntity.ZOffset.values()[index], TextBlockEntity.ZOffset::ordinal), C2SEditRecipeBlock::offset, - PacketCodecs.FLOAT, C2SEditRecipeBlock::rotationX, - PacketCodecs.FLOAT, C2SEditRecipeBlock::rotationY, + public static final Type ID = new Type<>(Glowcase.id("channel.recipe.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditRecipeBlock::pos, + ByteBufCodecs.STRING_UTF8, C2SEditRecipeBlock::recipe, + ByteBufCodecs.INT.map(index -> TextBlockEntity.ZOffset.values()[index], TextBlockEntity.ZOffset::ordinal), C2SEditRecipeBlock::offset, + ByteBufCodecs.FLOAT, C2SEditRecipeBlock::rotationX, + ByteBufCodecs.FLOAT, C2SEditRecipeBlock::rotationY, C2SEditRecipeBlock::new ); public static C2SEditRecipeBlock of(RecipeBlockEntity be) { - return new C2SEditRecipeBlock(be.getPos(), be.recipe, be.zOffset, be.rotationX, be.rotationY); + return new C2SEditRecipeBlock(be.getBlockPos(), be.recipe, be.zOffset, be.rotationX, be.rotationY); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof RecipeBlockEntity be)) return; be.setRecipe(this.recipe()); @@ -40,6 +40,6 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { be.rotationX = this.rotationX(); be.rotationY = this.rotationY(); - be.markDirty(); + be.setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditScreenBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditScreenBlock.java index d783bf7d..402e3040 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditScreenBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditScreenBlock.java @@ -3,60 +3,60 @@ import com.mojang.datafixers.util.Pair; import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.ScreenBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditScreenBlock(BlockPos pos, float width, float height, ScreenBlockEntity.Offset xOffset, ScreenBlockEntity.Offset yOffset, ScreenBlockEntity.Offset zOffset, float pitch, float yaw, boolean renderBackface, boolean eink, boolean stretch, String url, String alt, float preciseX, float preciseY, float preciseZ) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.screen_block")); - public static final PacketCodec PACKET_CODEC = PacketCodec.of( + public static final Type ID = new Type<>(Glowcase.id("channel.screen_block")); + public static final StreamCodec PACKET_CODEC = StreamCodec.ofMember( (packet, buf) -> { Pair trimmed = ScreenBlockEntity.trimStr(packet.url, packet.alt); - BlockPos.PACKET_CODEC.encode(buf, packet.pos); - PacketCodecs.FLOAT.encode(buf, packet.width); - PacketCodecs.FLOAT.encode(buf, packet.height); - PacketCodecs.BYTE.encode(buf, (byte) packet.xOffset.ordinal()); - PacketCodecs.BYTE.encode(buf, (byte) packet.yOffset.ordinal()); - PacketCodecs.BYTE.encode(buf, (byte) packet.zOffset.ordinal()); - PacketCodecs.FLOAT.encode(buf, packet.pitch); - PacketCodecs.FLOAT.encode(buf, packet.yaw); - PacketCodecs.BOOLEAN.encode(buf, packet.renderBackface); - PacketCodecs.BOOLEAN.encode(buf, packet.eink); - PacketCodecs.BOOLEAN.encode(buf, packet.stretch); - PacketCodecs.STRING.encode(buf, trimmed.getFirst()); - PacketCodecs.STRING.encode(buf, trimmed.getSecond()); - PacketCodecs.FLOAT.encode(buf, packet.preciseX); - PacketCodecs.FLOAT.encode(buf, packet.preciseY); - PacketCodecs.FLOAT.encode(buf, packet.preciseZ); + BlockPos.STREAM_CODEC.encode(buf, packet.pos); + ByteBufCodecs.FLOAT.encode(buf, packet.width); + ByteBufCodecs.FLOAT.encode(buf, packet.height); + ByteBufCodecs.BYTE.encode(buf, (byte) packet.xOffset.ordinal()); + ByteBufCodecs.BYTE.encode(buf, (byte) packet.yOffset.ordinal()); + ByteBufCodecs.BYTE.encode(buf, (byte) packet.zOffset.ordinal()); + ByteBufCodecs.FLOAT.encode(buf, packet.pitch); + ByteBufCodecs.FLOAT.encode(buf, packet.yaw); + ByteBufCodecs.BOOL.encode(buf, packet.renderBackface); + ByteBufCodecs.BOOL.encode(buf, packet.eink); + ByteBufCodecs.BOOL.encode(buf, packet.stretch); + ByteBufCodecs.STRING_UTF8.encode(buf, trimmed.getFirst()); + ByteBufCodecs.STRING_UTF8.encode(buf, trimmed.getSecond()); + ByteBufCodecs.FLOAT.encode(buf, packet.preciseX); + ByteBufCodecs.FLOAT.encode(buf, packet.preciseY); + ByteBufCodecs.FLOAT.encode(buf, packet.preciseZ); }, - (buf) -> new C2SEditScreenBlock(BlockPos.PACKET_CODEC.decode(buf), - PacketCodecs.FLOAT.decode(buf), - PacketCodecs.FLOAT.decode(buf), - ScreenBlockEntity.Offset.values()[PacketCodecs.BYTE.decode(buf)], - ScreenBlockEntity.Offset.values()[PacketCodecs.BYTE.decode(buf)], - ScreenBlockEntity.Offset.values()[PacketCodecs.BYTE.decode(buf)], - PacketCodecs.FLOAT.decode(buf), - PacketCodecs.FLOAT.decode(buf), - PacketCodecs.BOOLEAN.decode(buf), - PacketCodecs.BOOLEAN.decode(buf), - PacketCodecs.BOOLEAN.decode(buf), - PacketCodecs.STRING.decode(buf), - PacketCodecs.STRING.decode(buf), - PacketCodecs.FLOAT.decode(buf), - PacketCodecs.FLOAT.decode(buf), - PacketCodecs.FLOAT.decode(buf)) + (buf) -> new C2SEditScreenBlock(BlockPos.STREAM_CODEC.decode(buf), + ByteBufCodecs.FLOAT.decode(buf), + ByteBufCodecs.FLOAT.decode(buf), + ScreenBlockEntity.Offset.values()[ByteBufCodecs.BYTE.decode(buf)], + ScreenBlockEntity.Offset.values()[ByteBufCodecs.BYTE.decode(buf)], + ScreenBlockEntity.Offset.values()[ByteBufCodecs.BYTE.decode(buf)], + ByteBufCodecs.FLOAT.decode(buf), + ByteBufCodecs.FLOAT.decode(buf), + ByteBufCodecs.BOOL.decode(buf), + ByteBufCodecs.BOOL.decode(buf), + ByteBufCodecs.BOOL.decode(buf), + ByteBufCodecs.STRING_UTF8.decode(buf), + ByteBufCodecs.STRING_UTF8.decode(buf), + ByteBufCodecs.FLOAT.decode(buf), + ByteBufCodecs.FLOAT.decode(buf), + ByteBufCodecs.FLOAT.decode(buf)) ); public static C2SEditScreenBlock of(ScreenBlockEntity be) { - return new C2SEditScreenBlock(be.getPos(), be.width, be.height, be.xOffset, be.yOffset, be.zOffset, be.pitch, be.yaw, be.renderBackface, be.eink, be.stretch, be.url, be.alt, be.preciseX, be.preciseY, be.preciseZ); + return new C2SEditScreenBlock(be.getBlockPos(), be.width, be.height, be.xOffset, be.yOffset, be.zOffset, be.pitch, be.yaw, be.renderBackface, be.eink, be.stretch, be.url, be.alt, be.preciseX, be.preciseY, be.preciseZ); } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof ScreenBlockEntity be)) return; Pair trimmed = ScreenBlockEntity.trimStr(url, alt); @@ -71,7 +71,7 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { } @Override - public Id getId() { + public Type type() { return ID; } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSoundBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSoundBlock.java index 8ddce294..bf589697 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSoundBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSoundBlock.java @@ -2,23 +2,23 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.SoundPlayerBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundCategory; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.Identifier; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.Vec3; public record C2SEditSoundBlock(SoundInfo soundInfo, PositionalInfo positionalInfo, BlockPos blockPos) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.sound_block.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( + public static final Type ID = new Type<>(Glowcase.id("channel.sound_block.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( SoundInfo.PACKET_CODEC, C2SEditSoundBlock::soundInfo, PositionalInfo.PACKET_CODEC, C2SEditSoundBlock::positionalInfo, - BlockPos.PACKET_CODEC, C2SEditSoundBlock::blockPos, + BlockPos.STREAM_CODEC, C2SEditSoundBlock::blockPos, C2SEditSoundBlock::new ); @@ -26,12 +26,12 @@ public static C2SEditSoundBlock of(SoundPlayerBlockEntity be) { return new C2SEditSoundBlock( new SoundInfo(be.soundId, be.category.toString(), be.volume, be.pitch, be.repeatDelay, be.cancelOthers), new PositionalInfo(be.distance, be.relative, be.offset), - be.getPos() + be.getBlockPos() ); } @Override - public Id getId() { + public Type type() { return ID; } @@ -41,11 +41,11 @@ public BlockPos pos() { } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof SoundPlayerBlockEntity be)) return; be.soundId = soundInfo.id; - be.category = SoundCategory.valueOf(soundInfo.category); + be.category = SoundSource.valueOf(soundInfo.category); be.volume = soundInfo.volume; be.pitch = soundInfo.pitch; be.repeatDelay = soundInfo.repeatDelay; @@ -55,26 +55,26 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { be.relative = positionalInfo.relative; be.offset = positionalInfo.offset; - be.markDirty(); + be.setChanged(); } public record SoundInfo(Identifier id, String category, float volume, float pitch, int repeatDelay, boolean cancelOthers) { - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - Identifier.PACKET_CODEC, SoundInfo::id, - PacketCodecs.STRING, SoundInfo::category, - PacketCodecs.FLOAT, SoundInfo::volume, - PacketCodecs.FLOAT, SoundInfo::pitch, - PacketCodecs.INTEGER, SoundInfo::repeatDelay, - PacketCodecs.BOOLEAN, SoundInfo::cancelOthers, + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + Identifier.STREAM_CODEC, SoundInfo::id, + ByteBufCodecs.STRING_UTF8, SoundInfo::category, + ByteBufCodecs.FLOAT, SoundInfo::volume, + ByteBufCodecs.FLOAT, SoundInfo::pitch, + ByteBufCodecs.INT, SoundInfo::repeatDelay, + ByteBufCodecs.BOOL, SoundInfo::cancelOthers, SoundInfo::new ); } - public record PositionalInfo(float distance, boolean relative, Vec3d offset) { - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - PacketCodecs.FLOAT, PositionalInfo::distance, - PacketCodecs.BOOLEAN, PositionalInfo::relative, - PacketCodecs.codec(Vec3d.CODEC), PositionalInfo::offset, + public record PositionalInfo(float distance, boolean relative, Vec3 offset) { + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + ByteBufCodecs.FLOAT, PositionalInfo::distance, + ByteBufCodecs.BOOL, PositionalInfo::relative, + ByteBufCodecs.fromCodec(Vec3.CODEC), PositionalInfo::offset, PositionalInfo::new ); } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSpriteBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSpriteBlock.java index 9227caa2..76114463 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSpriteBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditSpriteBlock.java @@ -3,37 +3,37 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.SpriteBlockEntity; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditSpriteBlock(BlockPos pos, String sprite, int rotation, TextBlockEntity.ZOffset offset, int color, float scale) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.sprite.save")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditSpriteBlock::pos, - PacketCodecs.STRING, C2SEditSpriteBlock::sprite, - PacketCodecs.INTEGER, C2SEditSpriteBlock::rotation, - PacketCodecs.INTEGER.xmap(index -> TextBlockEntity.ZOffset.values()[index], TextBlockEntity.ZOffset::ordinal), C2SEditSpriteBlock::offset, - PacketCodecs.INTEGER, C2SEditSpriteBlock::color, - PacketCodecs.FLOAT, C2SEditSpriteBlock::scale, + public static final Type ID = new Type<>(Glowcase.id("channel.sprite.save")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditSpriteBlock::pos, + ByteBufCodecs.STRING_UTF8, C2SEditSpriteBlock::sprite, + ByteBufCodecs.INT, C2SEditSpriteBlock::rotation, + ByteBufCodecs.INT.map(index -> TextBlockEntity.ZOffset.values()[index], TextBlockEntity.ZOffset::ordinal), C2SEditSpriteBlock::offset, + ByteBufCodecs.INT, C2SEditSpriteBlock::color, + ByteBufCodecs.FLOAT, C2SEditSpriteBlock::scale, C2SEditSpriteBlock::new ); public static C2SEditSpriteBlock of(SpriteBlockEntity be) { - return new C2SEditSpriteBlock(be.getPos(), be.getSprite(), be.rotation, be.zOffset, be.color, be.scale); + return new C2SEditSpriteBlock(be.getBlockPos(), be.getSprite(), be.rotation, be.zOffset, be.color, be.scale); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof SpriteBlockEntity be)) return; be.setSprite(this.sprite()); @@ -42,6 +42,6 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { be.color = this.color(); be.scale = this.scale(); - be.markDirty(); + be.setChanged(); } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTabletItem.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTabletItem.java index e0a5e44f..55178164 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTabletItem.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTabletItem.java @@ -5,20 +5,19 @@ import dev.hephaestus.glowcase.block.entity.ScreenBlockEntity; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.item.ItemStack; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; - +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.item.ItemStack; import java.util.ArrayList; -public record C2SEditTabletItem(int index, String url, String alt) implements CustomPayload { - public static final Id ID = new Id<>(Glowcase.id("channel.slide_tablet")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - PacketCodecs.INTEGER, C2SEditTabletItem::index, - PacketCodecs.STRING, C2SEditTabletItem::url, - PacketCodecs.STRING, C2SEditTabletItem::alt, +public record C2SEditTabletItem(int index, String url, String alt) implements CustomPacketPayload { + public static final Type ID = new Type<>(Glowcase.id("channel.slide_tablet")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, C2SEditTabletItem::index, + ByteBufCodecs.STRING_UTF8, C2SEditTabletItem::url, + ByteBufCodecs.STRING_UTF8, C2SEditTabletItem::alt, C2SEditTabletItem::new ); @@ -28,8 +27,8 @@ public static C2SEditTabletItem of(int index, String url, String alt) { } public void receive(ServerPlayNetworking.Context context) { - ItemStack stack = context.player().getMainHandStack(); - if (!(stack.isOf(Glowcase.TABLET_ITEM.get()))) return; + ItemStack stack = context.player().getMainHandItem(); + if (!(stack.is(Glowcase.TABLET_ITEM.get()))) return; Pair trimmed = ScreenBlockEntity.trimStr(this.url, this.alt); Pair slide = new Pair<>(trimmed.getFirst(), trimmed.getSecond()); @@ -64,7 +63,7 @@ public void send() { } @Override - public Id getId() { + public Type type() { return ID; } } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTextBlock.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTextBlock.java index 6c8cb56c..79ea677b 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTextBlock.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SEditTextBlock.java @@ -2,41 +2,40 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.Text; -import net.minecraft.text.TextCodecs; -import net.minecraft.util.math.BlockPos; - import java.util.ArrayList; import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; public record C2SEditTextBlock(BlockPos pos, TextBlockEntity.TextAlignment alignment, TextBlockEntity.ZOffset offset, TextBlockValues values) implements C2SEditBlockEntity { - public static final Id ID = new Id<>(Glowcase.id("channel.text_block")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - BlockPos.PACKET_CODEC, C2SEditTextBlock::pos, - PacketCodecs.BYTE.xmap(index -> TextBlockEntity.TextAlignment.values()[index], textAlignment -> (byte) textAlignment.ordinal()), C2SEditTextBlock::alignment, - PacketCodecs.BYTE.xmap(index -> TextBlockEntity.ZOffset.values()[index], zOffset -> (byte) zOffset.ordinal()), C2SEditTextBlock::offset, + public static final Type ID = new Type<>(Glowcase.id("channel.text_block")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, C2SEditTextBlock::pos, + ByteBufCodecs.BYTE.map(index -> TextBlockEntity.TextAlignment.values()[index], textAlignment -> (byte) textAlignment.ordinal()), C2SEditTextBlock::alignment, + ByteBufCodecs.BYTE.map(index -> TextBlockEntity.ZOffset.values()[index], zOffset -> (byte) zOffset.ordinal()), C2SEditTextBlock::offset, TextBlockValues.PACKET_CODEC, C2SEditTextBlock::values, C2SEditTextBlock::new ); public static C2SEditTextBlock of(TextBlockEntity be) { - return new C2SEditTextBlock(be.getPos(), be.textAlignment, be.zOffset, new TextBlockValues(be.shadow, be.scale, be.backgroundColor, be.color, be.lines, be.viewDistance)); + return new C2SEditTextBlock(be.getBlockPos(), be.textAlignment, be.zOffset, new TextBlockValues(be.shadow, be.scale, be.backgroundColor, be.color, be.lines, be.viewDistance)); } @Override - public Id getId() { + public Type type() { return ID; } @Override - public void receive(ServerWorld world, BlockEntity blockEntity) { + public void receive(ServerLevel world, BlockEntity blockEntity) { if (!(blockEntity instanceof TextBlockEntity be)) return; be.shadow = this.values().shadow(); @@ -48,19 +47,19 @@ public void receive(ServerWorld world, BlockEntity blockEntity) { be.zOffset = this.offset(); be.viewDistance = this.values().viewDistance(); - be.markDirty(); + be.setChanged(); } // separated for tuple call - public record TextBlockValues(boolean shadow, float scale, int backgroundColor, int color, List lines, + public record TextBlockValues(boolean shadow, float scale, int backgroundColor, int color, List lines, float viewDistance) { - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - PacketCodecs.BOOLEAN, TextBlockValues::shadow, - PacketCodecs.FLOAT, TextBlockValues::scale, - PacketCodecs.INTEGER, TextBlockValues::backgroundColor, - PacketCodecs.INTEGER, TextBlockValues::color, - PacketCodecs.collection(ArrayList::new, TextCodecs.REGISTRY_PACKET_CODEC), TextBlockValues::lines, - PacketCodecs.FLOAT, TextBlockValues::viewDistance, + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, TextBlockValues::shadow, + ByteBufCodecs.FLOAT, TextBlockValues::scale, + ByteBufCodecs.INT, TextBlockValues::backgroundColor, + ByteBufCodecs.INT, TextBlockValues::color, + ByteBufCodecs.collection(ArrayList::new, ComponentSerialization.STREAM_CODEC), TextBlockValues::lines, + ByteBufCodecs.FLOAT, TextBlockValues::viewDistance, TextBlockValues::new ); } diff --git a/src/main/java/dev/hephaestus/glowcase/packet/C2SSlotScrolled.java b/src/main/java/dev/hephaestus/glowcase/packet/C2SSlotScrolled.java index cee046aa..12de45aa 100644 --- a/src/main/java/dev/hephaestus/glowcase/packet/C2SSlotScrolled.java +++ b/src/main/java/dev/hephaestus/glowcase/packet/C2SSlotScrolled.java @@ -1,23 +1,23 @@ package dev.hephaestus.glowcase.packet; import dev.hephaestus.glowcase.Glowcase; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.network.packet.CustomPayload; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -public record C2SSlotScrolled(int syncId, int revision, int slotIndex, int amount) implements CustomPayload { - public static final Id ID = new Id<>(Glowcase.id("slot_scrolled")); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - PacketCodecs.VAR_INT, C2SSlotScrolled::syncId, - PacketCodecs.VAR_INT, C2SSlotScrolled::revision, - PacketCodecs.VAR_INT, C2SSlotScrolled::slotIndex, - PacketCodecs.VAR_INT, C2SSlotScrolled::amount, +public record C2SSlotScrolled(int syncId, int revision, int slotIndex, int amount) implements CustomPacketPayload { + public static final Type ID = new Type<>(Glowcase.id("slot_scrolled")); + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, C2SSlotScrolled::syncId, + ByteBufCodecs.VAR_INT, C2SSlotScrolled::revision, + ByteBufCodecs.VAR_INT, C2SSlotScrolled::slotIndex, + ByteBufCodecs.VAR_INT, C2SSlotScrolled::amount, C2SSlotScrolled::new ); @Override - public Id getId() { + public Type type() { return ID; } } diff --git a/src/main/java/dev/hephaestus/glowcase/util/CollectableStack.java b/src/main/java/dev/hephaestus/glowcase/util/CollectableStack.java index e18f3f53..baf9e49f 100644 --- a/src/main/java/dev/hephaestus/glowcase/util/CollectableStack.java +++ b/src/main/java/dev/hephaestus/glowcase/util/CollectableStack.java @@ -2,23 +2,23 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.block.jukebox.JukeboxSong; -import net.minecraft.component.ComponentChanges; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.JukeboxPlayableComponent; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; +import net.minecraft.ChatFormatting; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.JukeboxPlayable; +import net.minecraft.world.item.JukeboxSong; -public record CollectableStack(RegistryEntry item, ComponentChanges changes, int count, boolean collected) { +public record CollectableStack(Holder item, DataComponentPatch changes, int count, boolean collected) { public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( - Item.ENTRY_CODEC.fieldOf("item").forGetter(CollectableStack::item), - ComponentChanges.CODEC.fieldOf("components").forGetter(CollectableStack::changes), + Item.CODEC.fieldOf("item").forGetter(CollectableStack::item), + DataComponentPatch.CODEC.fieldOf("components").forGetter(CollectableStack::changes), Codec.INT.fieldOf("count").forGetter(CollectableStack::count), Codec.BOOL.fieldOf("collected").forGetter(CollectableStack::collected) ).apply(instance, CollectableStack::new) @@ -28,17 +28,17 @@ public ItemStack getStack() { return new ItemStack(item, count, changes); } - public MutableText getCollectableName(RegistryWrapper.WrapperLookup lookup, boolean selected) { + public MutableComponent getCollectableName(HolderLookup.Provider lookup, boolean selected) { ItemStack stack = getStack(); - Text name = stack.getName(); - JukeboxPlayableComponent songComponent = stack.get(DataComponentTypes.JUKEBOX_PLAYABLE); + Component name = stack.getHoverName(); + JukeboxPlayable songComponent = stack.get(DataComponents.JUKEBOX_PLAYABLE); if (songComponent != null) { - JukeboxSong song = songComponent.song().resolveEntry(lookup).map(RegistryEntry::value).orElse(null); + JukeboxSong song = songComponent.song().value(); if (song != null) { name = song.description(); } } - return Text.literal("%s %dx ".formatted(selected ? ">" : "-", count)).append(name).formatted(collected ? Formatting.AQUA : Formatting.GRAY).styled(selected ? s -> s.withBold(true) : s -> s); + return Component.literal("%s %dx ".formatted(selected ? ">" : "-", count)).append(name).withStyle(collected ? ChatFormatting.AQUA : ChatFormatting.GRAY).withStyle(selected ? s -> s.withBold(true) : s -> s); } public CollectableStack asCollected() { diff --git a/src/main/java/dev/hephaestus/glowcase/util/DeviatedInteger.java b/src/main/java/dev/hephaestus/glowcase/util/DeviatedInteger.java index 167ca7f6..c0208819 100644 --- a/src/main/java/dev/hephaestus/glowcase/util/DeviatedInteger.java +++ b/src/main/java/dev/hephaestus/glowcase/util/DeviatedInteger.java @@ -3,11 +3,10 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.netty.buffer.ByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.util.math.MathHelper; - import java.util.function.Supplier; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.util.Mth; public record DeviatedInteger(Integer mean, Integer stdDev) implements DeviatedValue { public static final DeviatedInteger ZERO = new DeviatedInteger(0, 0); @@ -17,16 +16,16 @@ public record DeviatedInteger(Integer mean, Integer stdDev) implements DeviatedV Codec.INT.fieldOf("std_dev").forGetter(DeviatedInteger::stdDev) ).apply(instance, DeviatedInteger::new)); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - PacketCodecs.VAR_INT, + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, DeviatedInteger::mean, - PacketCodecs.VAR_INT, + ByteBufCodecs.VAR_INT, DeviatedInteger::stdDev, DeviatedInteger::new ); @Override public Integer get(Supplier random) { - return mean + MathHelper.floor(random.get() * stdDev); + return mean + Mth.floor(random.get() * stdDev); } } diff --git a/src/main/java/dev/hephaestus/glowcase/util/DeviatedVec3d.java b/src/main/java/dev/hephaestus/glowcase/util/DeviatedVec3d.java index ad2ac02f..3b7abc49 100644 --- a/src/main/java/dev/hephaestus/glowcase/util/DeviatedVec3d.java +++ b/src/main/java/dev/hephaestus/glowcase/util/DeviatedVec3d.java @@ -3,30 +3,29 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.netty.buffer.ByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.util.math.Vec3d; - import java.util.function.Supplier; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.phys.Vec3; -public record DeviatedVec3d(Vec3d mean, Vec3d stdDev) implements DeviatedValue { - public static final DeviatedVec3d ZERO = new DeviatedVec3d(Vec3d.ZERO, Vec3d.ZERO); +public record DeviatedVec3d(Vec3 mean, Vec3 stdDev) implements DeviatedValue { + public static final DeviatedVec3d ZERO = new DeviatedVec3d(Vec3.ZERO, Vec3.ZERO); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Vec3d.CODEC.fieldOf("mean").forGetter(DeviatedVec3d::mean), - Vec3d.CODEC.fieldOf("std_dev").forGetter(DeviatedVec3d::stdDev) + Vec3.CODEC.fieldOf("mean").forGetter(DeviatedVec3d::mean), + Vec3.CODEC.fieldOf("std_dev").forGetter(DeviatedVec3d::stdDev) ).apply(instance, DeviatedVec3d::new)); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - Vec3d.PACKET_CODEC, + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + Vec3.STREAM_CODEC, DeviatedVec3d::mean, - Vec3d.PACKET_CODEC, + Vec3.STREAM_CODEC, DeviatedVec3d::stdDev, DeviatedVec3d::new ); @Override - public Vec3d get(Supplier random) { - return new Vec3d( + public Vec3 get(Supplier random) { + return new Vec3( mean.x + random.get() * stdDev.x, mean.y + random.get() * stdDev.y, mean.z + random.get() * stdDev.z diff --git a/src/main/java/dev/hephaestus/glowcase/util/DisplayBlockSettings.java b/src/main/java/dev/hephaestus/glowcase/util/DisplayBlockSettings.java index e1fa34b1..fe943599 100644 --- a/src/main/java/dev/hephaestus/glowcase/util/DisplayBlockSettings.java +++ b/src/main/java/dev/hephaestus/glowcase/util/DisplayBlockSettings.java @@ -3,26 +3,27 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.netty.buffer.ByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.util.dynamic.Codecs; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.util.ExtraCodecs; import org.joml.Vector3f; +import org.joml.Vector3fc; -public record DisplayBlockSettings(Vector3f offset, Vector3f scale, float pitch, float yaw, boolean renderAsBlock) { +public record DisplayBlockSettings(Vector3fc offset, Vector3fc scale, float pitch, float yaw, boolean renderAsBlock) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codecs.VECTOR_3F.lenientOptionalFieldOf("offset", new Vector3f()).forGetter(DisplayBlockSettings::offset), - Codecs.VECTOR_3F.lenientOptionalFieldOf("scale", new Vector3f(1.0F)).forGetter(DisplayBlockSettings::scale), + ExtraCodecs.VECTOR3F.lenientOptionalFieldOf("offset", new Vector3f()).forGetter(DisplayBlockSettings::offset), + ExtraCodecs.VECTOR3F.lenientOptionalFieldOf("scale", new Vector3f(1.0F)).forGetter(DisplayBlockSettings::scale), Codec.FLOAT.lenientOptionalFieldOf("pitch", 0F).forGetter(DisplayBlockSettings::pitch), Codec.FLOAT.lenientOptionalFieldOf("yaw", 0F).forGetter(DisplayBlockSettings::yaw), Codec.BOOL.lenientOptionalFieldOf("renderAsBlock", false).forGetter(DisplayBlockSettings::renderAsBlock) ).apply(instance, DisplayBlockSettings::new)); - public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( - PacketCodecs.VECTOR_3F, DisplayBlockSettings::offset, - PacketCodecs.VECTOR_3F, DisplayBlockSettings::scale, - PacketCodecs.FLOAT, DisplayBlockSettings::pitch, - PacketCodecs.FLOAT, DisplayBlockSettings::yaw, - PacketCodecs.BOOLEAN, DisplayBlockSettings::renderAsBlock, + public static final StreamCodec PACKET_CODEC = StreamCodec.composite( + ByteBufCodecs.VECTOR3F, DisplayBlockSettings::offset, + ByteBufCodecs.VECTOR3F, DisplayBlockSettings::scale, + ByteBufCodecs.FLOAT, DisplayBlockSettings::pitch, + ByteBufCodecs.FLOAT, DisplayBlockSettings::yaw, + ByteBufCodecs.BOOL, DisplayBlockSettings::renderAsBlock, DisplayBlockSettings::new ); diff --git a/src/main/java/dev/hephaestus/glowcase/util/EmiUtils.java b/src/main/java/dev/hephaestus/glowcase/util/EmiUtils.java index e0dbc31d..dceac4f3 100644 --- a/src/main/java/dev/hephaestus/glowcase/util/EmiUtils.java +++ b/src/main/java/dev/hephaestus/glowcase/util/EmiUtils.java @@ -4,15 +4,7 @@ //import dev.emi.emi.api.recipe.EmiRecipe; import dev.hephaestus.glowcase.block.entity.RecipeBlockEntity; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.command.argument.BlockPosArgumentType; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockBox; -import net.minecraft.util.math.BlockPos; - +import net.minecraft.resources.Identifier; import java.util.List; import java.util.Objects; diff --git a/src/main/java/dev/hephaestus/glowcase/util/TextUtils.java b/src/main/java/dev/hephaestus/glowcase/util/TextUtils.java index b546b93f..b774f338 100644 --- a/src/main/java/dev/hephaestus/glowcase/util/TextUtils.java +++ b/src/main/java/dev/hephaestus/glowcase/util/TextUtils.java @@ -1,13 +1,13 @@ package dev.hephaestus.glowcase.util; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; public class TextUtils { - public static final Style PLACEHOLDER_STYLE = Style.EMPTY.withItalic(true).withColor(Formatting.GRAY); + public static final Style PLACEHOLDER_STYLE = Style.EMPTY.withItalic(true).withColor(ChatFormatting.GRAY); - public static Text placeholder(String key) { - return Text.translatable(key).setStyle(PLACEHOLDER_STYLE); + public static Component placeholder(String key) { + return Component.translatable(key).setStyle(PLACEHOLDER_STYLE); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index ed816878..6c910633 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -28,7 +28,7 @@ "placeholder-api": ">=${placeholder}" }, "suggests": { - "polydex": ">=${polydex}" + "polydex": "*" }, "entrypoints": { "fabric-datagen": [ diff --git a/src/main/resources/glowcase.accesswidener b/src/main/resources/glowcase.accesswidener index c786960d..15c72daf 100644 --- a/src/main/resources/glowcase.accesswidener +++ b/src/main/resources/glowcase.accesswidener @@ -1,9 +1,10 @@ -accessWidener v2 named +accessWidener v2 official -accessible class net/minecraft/client/font/TextRenderer$Drawer +accessible class net/minecraft/client/gui/Font$PreparedTextBuilder accessible class net/minecraft/client/gui/render/GuiRenderer$Draw -accessible method net/minecraft/client/gui/DrawContext drawTexturedQuad (Lcom/mojang/blaze3d/pipeline/RenderPipeline;Lcom/mojang/blaze3d/textures/GpuTextureView;IIIIFFFFI)V -accessible method net/minecraft/client/gui/widget/TextFieldWidget onChanged (Ljava/lang/String;)V +#accessible method net/minecraft/client/gui/GuiGraphics submitBlit (Lcom/mojang/blaze3d/pipeline/RenderPipeline;Lcom/mojang/blaze3d/textures/GpuTextureView;IIIIFFFFI)V +accessible method net/minecraft/client/gui/GuiGraphics submitBlit (Lcom/mojang/blaze3d/pipeline/RenderPipeline;Lcom/mojang/blaze3d/textures/GpuTextureView;Lcom/mojang/blaze3d/textures/GpuSampler;IIIIFFFFI)V +accessible method net/minecraft/client/gui/components/EditBox onValueChange (Ljava/lang/String;)V -accessible field net/minecraft/client/data/BlockStateModelGenerator NORTH_DEFAULT_ROTATION_OPERATIONS Lnet/minecraft/client/data/BlockStateVariantMap; +accessible field net/minecraft/client/data/models/BlockModelGenerators ROTATION_FACING Lnet/minecraft/client/data/models/blockstates/PropertyDispatch; diff --git a/src/main/resources/glowcase.mixins.json b/src/main/resources/glowcase.mixins.json index 2b039a07..692b41c4 100644 --- a/src/main/resources/glowcase.mixins.json +++ b/src/main/resources/glowcase.mixins.json @@ -4,22 +4,20 @@ "package": "dev.hephaestus.glowcase.mixin", "compatibilityLevel": "JAVA_21", "mixins": [ - "LockableContainerBlockEntityAccessor", - "PlayerEntityMixin" + "BaseContainerBlockEntityAccessor", + "PlayerMixin" ], "client": [ - "HandledScreenInvoker", + "AbstractContainerScreenInvoker", "client.GameRendererAccessor", "client.GuiRendererMixin", - "client.KeyboardMixin", - "client.MixinHeldItemRenderer", - "client.MixinInGameHud", - "client.MultiPhaseRenderLayerAccessor", - "client.RenderLayerMultiPhaseParametersAccessor", - "client.TextRendererAccessor", + "client.KeyboardHandlerMixin", + "client.ItemInHandRendererMixin", + "client.GuiMixin", + "client.FontAccessor", "client.TextureManagerAccessor", "client.sound.SoundManagerMixin", - "client.sound.SoundSystemMixin" + "client.sound.SoundEngineMixin" ], "server": [], "injectors": {